cargo fmt
This commit is contained in:
parent
f7ff84d2a0
commit
8ccb93d8eb
15 changed files with 460 additions and 239 deletions
6
build.rs
6
build.rs
|
|
@ -20,5 +20,9 @@ fn main() {
|
|||
let ext_workspace_protocol_file = "resources/ext-workspace-unstable-v1.xml";
|
||||
// Target directory for the generate files
|
||||
generate_code(drm_protocol_file, &dest.join("wl_drm.rs"), Side::Server);
|
||||
generate_code(ext_workspace_protocol_file, &dest.join("ext_workspace.rs"), Side::Server);
|
||||
generate_code(
|
||||
ext_workspace_protocol_file,
|
||||
&dest.join("ext_workspace.rs"),
|
||||
Side::Server,
|
||||
);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -35,7 +35,7 @@ use smithay::{
|
|||
nix::{fcntl::OFlag, sys::stat::dev_t},
|
||||
wayland_server::protocol::wl_output,
|
||||
},
|
||||
utils::signaling::{Linkable, Signaler, SignalToken},
|
||||
utils::signaling::{Linkable, SignalToken, Signaler},
|
||||
wayland::output::{Mode as OutputMode, Output, PhysicalProperties},
|
||||
};
|
||||
|
||||
|
|
@ -172,7 +172,7 @@ pub fn init_backend(event_loop: &mut EventLoop<'static, State>, state: &mut Stat
|
|||
.handle()
|
||||
.register_dispatcher(udev_dispatcher.clone())
|
||||
.unwrap();
|
||||
|
||||
|
||||
let handle = event_loop.handle();
|
||||
let loop_signal = state.common.event_loop_signal.clone();
|
||||
let dispatcher = udev_dispatcher.clone();
|
||||
|
|
@ -184,29 +184,55 @@ pub fn init_backend(event_loop: &mut EventLoop<'static, State>, state: &mut Stat
|
|||
let drm_node = match DrmNode::from_dev_id(dev) {
|
||||
Ok(node) => node,
|
||||
Err(err) => {
|
||||
slog_scope::error!("Failed to read drm device {}: {}", path.display(), err);
|
||||
continue
|
||||
},
|
||||
slog_scope::error!(
|
||||
"Failed to read drm device {}: {}",
|
||||
path.display(),
|
||||
err
|
||||
);
|
||||
continue;
|
||||
}
|
||||
};
|
||||
if state.backend.kms().devices.contains_key(&drm_node) {
|
||||
if let Err(err) = state.device_changed(dev) {
|
||||
slog_scope::error!("Failed to update drm device {}: {}", path.display(), err);
|
||||
slog_scope::error!(
|
||||
"Failed to update drm device {}: {}",
|
||||
path.display(),
|
||||
err
|
||||
);
|
||||
}
|
||||
} else {
|
||||
if let Err(err) = state.device_added(dev, path.into()) {
|
||||
slog_scope::error!("Failed to add drm device {}: {}", path.display(), err);
|
||||
slog_scope::error!(
|
||||
"Failed to add drm device {}: {}",
|
||||
path.display(),
|
||||
err
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
state.common
|
||||
state
|
||||
.common
|
||||
.output_conf
|
||||
.update(&mut *state.common.display.borrow_mut());
|
||||
|
||||
state.common.config.read_outputs(state.common.output_conf.outputs(), &mut state.backend, &mut state.common.shell);
|
||||
state.common.config.read_outputs(
|
||||
state.common.output_conf.outputs(),
|
||||
&mut state.backend,
|
||||
&mut state.common.shell,
|
||||
);
|
||||
state.common.shell.refresh_outputs();
|
||||
state.common.config.write_outputs(state.common.output_conf.outputs());
|
||||
state
|
||||
.common
|
||||
.config
|
||||
.write_outputs(state.common.output_conf.outputs());
|
||||
|
||||
for surface in state.backend.kms().devices.values_mut().flat_map(|d| d.surfaces.values_mut()) {
|
||||
for surface in state
|
||||
.backend
|
||||
.kms()
|
||||
.devices
|
||||
.values_mut()
|
||||
.flat_map(|d| d.surfaces.values_mut())
|
||||
{
|
||||
surface.pending = false;
|
||||
}
|
||||
for output in state.common.shell.outputs() {
|
||||
|
|
@ -216,10 +242,14 @@ pub fn init_backend(event_loop: &mut EventLoop<'static, State>, state: &mut Stat
|
|||
loop_signal.wakeup();
|
||||
}
|
||||
});
|
||||
|
||||
|
||||
state.backend = BackendData::Kms(KmsState {
|
||||
api,
|
||||
_tokens: vec![libinput_event_source, session_event_source, udev_event_source],
|
||||
_tokens: vec![
|
||||
libinput_event_source,
|
||||
session_event_source,
|
||||
udev_event_source,
|
||||
],
|
||||
primary,
|
||||
session,
|
||||
signaler,
|
||||
|
|
@ -240,7 +270,7 @@ impl State {
|
|||
if !self.backend.kms().session.is_active() {
|
||||
return Ok(());
|
||||
}
|
||||
|
||||
|
||||
let fd = SessionFd::new(
|
||||
self.backend
|
||||
.kms()
|
||||
|
|
@ -352,33 +382,44 @@ impl State {
|
|||
let mut wl_outputs = Vec::new();
|
||||
let mut w = self.common.shell.global_space().size.w;
|
||||
for (crtc, conn) in outputs {
|
||||
match device.setup_surface(
|
||||
crtc,
|
||||
conn,
|
||||
&mut self.common.event_loop_handle,
|
||||
(0, w),
|
||||
) {
|
||||
match device.setup_surface(crtc, conn, &mut self.common.event_loop_handle, (0, w)) {
|
||||
Ok(output) => {
|
||||
w += output.user_data().get::<RefCell<OutputConfig>>().unwrap().borrow().mode_size().w;
|
||||
w += output
|
||||
.user_data()
|
||||
.get::<RefCell<OutputConfig>>()
|
||||
.unwrap()
|
||||
.borrow()
|
||||
.mode_size()
|
||||
.w;
|
||||
wl_outputs.push(output);
|
||||
}
|
||||
Err(err) => slog_scope::warn!("Failed to initialize output: {}", err),
|
||||
};
|
||||
}
|
||||
self.backend.kms().devices.insert(drm_node, device);
|
||||
|
||||
|
||||
self.common.output_conf.add_heads(wl_outputs.iter());
|
||||
self.common
|
||||
.output_conf
|
||||
.update(&mut *self.common.display.borrow_mut());
|
||||
for output in wl_outputs {
|
||||
if let Err(err) = self.backend.kms().apply_config_for_output(&output, &mut self.common.shell, false) {
|
||||
if let Err(err) =
|
||||
self.backend
|
||||
.kms()
|
||||
.apply_config_for_output(&output, &mut self.common.shell, false)
|
||||
{
|
||||
slog_scope::warn!("Failed to initialize output: {}", err);
|
||||
}
|
||||
}
|
||||
self.common.config.read_outputs(self.common.output_conf.outputs(), &mut self.backend, &mut self.common.shell);
|
||||
self.common.config.read_outputs(
|
||||
self.common.output_conf.outputs(),
|
||||
&mut self.backend,
|
||||
&mut self.common.shell,
|
||||
);
|
||||
self.common.shell.refresh_outputs();
|
||||
self.common.config.write_outputs(self.common.output_conf.outputs());
|
||||
self.common
|
||||
.config
|
||||
.write_outputs(self.common.output_conf.outputs());
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
|
@ -387,7 +428,7 @@ impl State {
|
|||
if !self.backend.kms().session.is_active() {
|
||||
return Ok(());
|
||||
}
|
||||
|
||||
|
||||
let drm_node = DrmNode::from_dev_id(dev)?;
|
||||
let mut outputs_removed = Vec::new();
|
||||
let mut outputs_added = Vec::new();
|
||||
|
|
@ -404,14 +445,15 @@ impl State {
|
|||
}
|
||||
}
|
||||
for (crtc, conn) in changes.added {
|
||||
match device.setup_surface(
|
||||
crtc,
|
||||
conn,
|
||||
&mut self.common.event_loop_handle,
|
||||
(0, w),
|
||||
) {
|
||||
match device.setup_surface(crtc, conn, &mut self.common.event_loop_handle, (0, w)) {
|
||||
Ok(output) => {
|
||||
w += output.user_data().get::<RefCell<OutputConfig>>().unwrap().borrow().mode_size().w;
|
||||
w += output
|
||||
.user_data()
|
||||
.get::<RefCell<OutputConfig>>()
|
||||
.unwrap()
|
||||
.borrow()
|
||||
.mode_size()
|
||||
.w;
|
||||
outputs_added.push(output);
|
||||
}
|
||||
Err(err) => slog_scope::warn!("Failed to initialize output: {}", err),
|
||||
|
|
@ -422,16 +464,26 @@ impl State {
|
|||
self.common.output_conf.remove_heads(outputs_removed.iter());
|
||||
self.common.output_conf.add_heads(outputs_added.iter());
|
||||
for output in outputs_added {
|
||||
if let Err(err) = self.backend.kms().apply_config_for_output(&output, &mut self.common.shell, false) {
|
||||
if let Err(err) =
|
||||
self.backend
|
||||
.kms()
|
||||
.apply_config_for_output(&output, &mut self.common.shell, false)
|
||||
{
|
||||
slog_scope::warn!("Failed to initialize output: {}", err);
|
||||
}
|
||||
}
|
||||
self.common
|
||||
.output_conf
|
||||
.update(&mut self.common.display.borrow_mut());
|
||||
self.common.config.read_outputs(self.common.output_conf.outputs(), &mut self.backend, &mut self.common.shell);
|
||||
self.common.config.read_outputs(
|
||||
self.common.output_conf.outputs(),
|
||||
&mut self.backend,
|
||||
&mut self.common.shell,
|
||||
);
|
||||
self.common.shell.refresh_outputs();
|
||||
self.common.config.write_outputs(self.common.output_conf.outputs());
|
||||
self.common
|
||||
.config
|
||||
.write_outputs(self.common.output_conf.outputs());
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
|
@ -459,9 +511,15 @@ impl State {
|
|||
.update(&mut *self.common.display.borrow_mut());
|
||||
|
||||
if self.backend.kms().session.is_active() {
|
||||
self.common.config.read_outputs(self.common.output_conf.outputs(), &mut self.backend, &mut self.common.shell);
|
||||
self.common.config.read_outputs(
|
||||
self.common.output_conf.outputs(),
|
||||
&mut self.backend,
|
||||
&mut self.common.shell,
|
||||
);
|
||||
self.common.shell.refresh_outputs();
|
||||
self.common.config.write_outputs(self.common.output_conf.outputs());
|
||||
self.common
|
||||
.config
|
||||
.write_outputs(self.common.output_conf.outputs());
|
||||
}
|
||||
|
||||
Ok(())
|
||||
|
|
@ -621,18 +679,11 @@ impl Surface {
|
|||
self.surface.as_mut().unwrap().reset_buffers();
|
||||
}
|
||||
|
||||
let workspace = state
|
||||
.shell
|
||||
.active_space(&self.output);
|
||||
let workspace = state.shell.active_space(&self.output);
|
||||
let nodes = workspace
|
||||
.get_fullscreen(&self.output)
|
||||
.map(|w| vec![w])
|
||||
.unwrap_or_else(||
|
||||
workspace
|
||||
.space
|
||||
.windows()
|
||||
.collect::<Vec<_>>()
|
||||
)
|
||||
.unwrap_or_else(|| workspace.space.windows().collect::<Vec<_>>())
|
||||
.into_iter()
|
||||
.flat_map(|w| {
|
||||
w.toplevel()
|
||||
|
|
@ -696,10 +747,7 @@ impl Surface {
|
|||
}
|
||||
|
||||
impl KmsState {
|
||||
pub fn switch_vt(
|
||||
&mut self,
|
||||
num: i32,
|
||||
) -> Result<(), anyhow::Error> {
|
||||
pub fn switch_vt(&mut self, num: i32) -> Result<(), anyhow::Error> {
|
||||
self.session.change_vt(num).map_err(Into::into)
|
||||
}
|
||||
|
||||
|
|
@ -823,7 +871,7 @@ impl KmsState {
|
|||
*/
|
||||
let data = (*device, *crtc);
|
||||
//if surface.vrr {
|
||||
surface.render_timer.add_timeout(Duration::ZERO, data);
|
||||
surface.render_timer.add_timeout(Duration::ZERO, data);
|
||||
//} else {
|
||||
// surface.render_timer.add_timeout(duration, data);
|
||||
//}
|
||||
|
|
|
|||
|
|
@ -12,7 +12,10 @@ pub mod x11;
|
|||
// TODO
|
||||
// pub mod wayland; // tbd in smithay
|
||||
|
||||
pub fn init_backend_auto(event_loop: &mut EventLoop<'static, State>, state: &mut State) -> Result<()> {
|
||||
pub fn init_backend_auto(
|
||||
event_loop: &mut EventLoop<'static, State>,
|
||||
state: &mut State,
|
||||
) -> Result<()> {
|
||||
match std::env::var("COSMIC_BACKEND") {
|
||||
Ok(x) if x == "x11" => x11::init_backend(event_loop, state),
|
||||
Ok(x) if x == "winit" => winit::init_backend(event_loop, state),
|
||||
|
|
|
|||
|
|
@ -14,18 +14,17 @@ use smithay::{
|
|||
renderer::{
|
||||
gles2::{Gles2Renderbuffer, Gles2Renderer, Gles2Texture},
|
||||
multigpu::{egl::EglGlesBackend, Error as MultiError, MultiFrame, MultiRenderer},
|
||||
ImportAll, Renderer, Frame, TextureFilter,
|
||||
Frame, ImportAll, Renderer, TextureFilter,
|
||||
},
|
||||
},
|
||||
desktop::{
|
||||
draw_layer_surface, draw_window, layer_map_for_output,
|
||||
space::{RenderElement, RenderError, SpaceOutputTuple, SurfaceTree},
|
||||
draw_window, draw_layer_surface, Window, layer_map_for_output, utils::damage_from_surface_tree,
|
||||
utils::damage_from_surface_tree,
|
||||
Window,
|
||||
},
|
||||
utils::{Logical, Point, Rectangle, Transform},
|
||||
wayland::{
|
||||
shell::wlr_layer::Layer as WlrLayer,
|
||||
output::Output,
|
||||
},
|
||||
wayland::{output::Output, shell::wlr_layer::Layer as WlrLayer},
|
||||
};
|
||||
|
||||
mod cursor;
|
||||
|
|
@ -115,7 +114,12 @@ pub fn needs_buffer_reset(output: &Output, state: &Common) -> bool {
|
|||
|
||||
let userdata = output.user_data();
|
||||
userdata.insert_if_missing(|| DidCustomRendering(AtomicBool::new(false)));
|
||||
userdata.get::<DidCustomRendering>().unwrap().0.swap(will_render_custom, Ordering::AcqRel) != will_render_custom
|
||||
userdata
|
||||
.get::<DidCustomRendering>()
|
||||
.unwrap()
|
||||
.0
|
||||
.swap(will_render_custom, Ordering::AcqRel)
|
||||
!= will_render_custom
|
||||
}
|
||||
|
||||
pub fn render_output<R>(
|
||||
|
|
@ -132,7 +136,9 @@ where
|
|||
<R as Renderer>::TextureId: Clone + 'static,
|
||||
CustomElem: RenderElement<R>,
|
||||
{
|
||||
renderer.downscale_filter(TextureFilter::Linear).map_err(RenderError::Rendering)?;
|
||||
renderer
|
||||
.downscale_filter(TextureFilter::Linear)
|
||||
.map_err(RenderError::Rendering)?;
|
||||
|
||||
#[cfg(feature = "debug")]
|
||||
{
|
||||
|
|
@ -259,10 +265,16 @@ where
|
|||
|
||||
#[cfg(feature = "debug")]
|
||||
{
|
||||
let fps_overlay = fps_ui(_gpu, state, fps, Rectangle::from_loc_and_size((0, 0), output_geo.size), scale);
|
||||
let fps_overlay = fps_ui(
|
||||
_gpu,
|
||||
state,
|
||||
fps,
|
||||
Rectangle::from_loc_and_size((0, 0), output_geo.size),
|
||||
scale,
|
||||
);
|
||||
custom_elements.push(fps_overlay.into());
|
||||
}
|
||||
|
||||
|
||||
for seat in &state.seats {
|
||||
let pointer = match seat.get_pointer() {
|
||||
Some(ptr) => ptr,
|
||||
|
|
|
|||
|
|
@ -183,9 +183,7 @@ pub fn init_backend(event_loop: &mut EventLoop<State>, state: &mut State) -> Res
|
|||
}
|
||||
Err(winit::WinitError::WindowClosed) => {
|
||||
let output = state.backend.winit().output.clone();
|
||||
state.common.shell.remove_output(
|
||||
&output,
|
||||
);
|
||||
state.common.shell.remove_output(&output);
|
||||
if let Some(token) = token.take() {
|
||||
event_loop_handle.remove(token);
|
||||
}
|
||||
|
|
@ -207,11 +205,12 @@ pub fn init_backend(event_loop: &mut EventLoop<State>, state: &mut State) -> Res
|
|||
.common
|
||||
.output_conf
|
||||
.update(&mut *state.common.display.borrow_mut());
|
||||
state
|
||||
.common
|
||||
.shell
|
||||
.add_output(&output);
|
||||
state.common.config.read_outputs(std::iter::once(&output), &mut state.backend, &mut state.common.shell);
|
||||
state.common.shell.add_output(&output);
|
||||
state.common.config.read_outputs(
|
||||
std::iter::once(&output),
|
||||
&mut state.backend,
|
||||
&mut state.common.shell,
|
||||
);
|
||||
state.common.shell.refresh_outputs();
|
||||
state.common.config.write_outputs(std::iter::once(&output));
|
||||
|
||||
|
|
|
|||
|
|
@ -263,16 +263,15 @@ pub fn init_backend(event_loop: &mut EventLoop<State>, state: &mut State) -> Res
|
|||
.common
|
||||
.output_conf
|
||||
.update(&mut *state.common.display.borrow_mut());
|
||||
state
|
||||
.common
|
||||
.shell
|
||||
.add_output(&output);
|
||||
state.common.config.read_outputs(std::iter::once(&output), &mut state.backend, &mut state.common.shell);
|
||||
state.common.shell.add_output(&output);
|
||||
state.common.config.read_outputs(
|
||||
std::iter::once(&output),
|
||||
&mut state.backend,
|
||||
&mut state.common.shell,
|
||||
);
|
||||
state.common.shell.refresh_outputs();
|
||||
state.common.config.write_outputs(std::iter::once(&output));
|
||||
|
||||
|
||||
|
||||
event_loop
|
||||
.handle()
|
||||
.insert_source(backend, |event, _, state| match event {
|
||||
|
|
@ -295,9 +294,7 @@ pub fn init_backend(event_loop: &mut EventLoop<State>, state: &mut State) -> Res
|
|||
.surfaces
|
||||
.retain(|s| s.window.id() != window_id);
|
||||
for output in outputs_removed.into_iter() {
|
||||
state.common.shell.remove_output(
|
||||
&output,
|
||||
);
|
||||
state.common.shell.remove_output(&output);
|
||||
}
|
||||
}
|
||||
X11Event::Resized {
|
||||
|
|
|
|||
|
|
@ -1,16 +1,16 @@
|
|||
// SPDX-License-Identifier: GPL-3.0-only
|
||||
|
||||
use crate::{
|
||||
shell::{
|
||||
Shell,
|
||||
layout::FocusDirection,
|
||||
},
|
||||
shell::{layout::FocusDirection, Shell},
|
||||
state::BackendData,
|
||||
};
|
||||
use serde::{Deserialize, Serialize};
|
||||
pub use smithay::{
|
||||
backend::input::KeyState,
|
||||
reexports::input::{AccelProfile, ClickMethod, ScrollMethod, SendEventsMode, TapButtonMap, Device as InputDevice},
|
||||
reexports::input::{
|
||||
AccelProfile, ClickMethod, Device as InputDevice, ScrollMethod, SendEventsMode,
|
||||
TapButtonMap,
|
||||
},
|
||||
utils::{Logical, Physical, Point, Size, Transform},
|
||||
wayland::{
|
||||
output::{Mode, Output},
|
||||
|
|
@ -116,24 +116,24 @@ pub struct InputsConfig {
|
|||
#[derive(Debug, Deserialize, Serialize)]
|
||||
pub struct InputConfig {
|
||||
state: DeviceState,
|
||||
#[serde(skip_serializing_if="Option::is_none", default)]
|
||||
#[serde(skip_serializing_if = "Option::is_none", default)]
|
||||
acceleration: Option<AccelConfig>,
|
||||
#[serde(skip_serializing_if="Option::is_none", default)]
|
||||
#[serde(skip_serializing_if = "Option::is_none", default)]
|
||||
calibration: Option<[f32; 6]>,
|
||||
#[serde(with = "ClickMethodDef")]
|
||||
#[serde(skip_serializing_if="Option::is_none", default)]
|
||||
#[serde(skip_serializing_if = "Option::is_none", default)]
|
||||
click_method: Option<ClickMethod>,
|
||||
#[serde(skip_serializing_if="Option::is_none", default)]
|
||||
#[serde(skip_serializing_if = "Option::is_none", default)]
|
||||
disable_while_typing: Option<bool>,
|
||||
#[serde(skip_serializing_if="Option::is_none", default)]
|
||||
#[serde(skip_serializing_if = "Option::is_none", default)]
|
||||
left_handed: Option<bool>,
|
||||
#[serde(skip_serializing_if="Option::is_none", default)]
|
||||
#[serde(skip_serializing_if = "Option::is_none", default)]
|
||||
middle_button_emulation: Option<bool>,
|
||||
#[serde(skip_serializing_if="Option::is_none", default)]
|
||||
#[serde(skip_serializing_if = "Option::is_none", default)]
|
||||
rotation_angle: Option<u32>,
|
||||
#[serde(skip_serializing_if="Option::is_none", default)]
|
||||
#[serde(skip_serializing_if = "Option::is_none", default)]
|
||||
scroll_config: Option<ScrollConfig>,
|
||||
#[serde(skip_serializing_if="Option::is_none", default)]
|
||||
#[serde(skip_serializing_if = "Option::is_none", default)]
|
||||
tap_config: Option<TapConfig>,
|
||||
}
|
||||
|
||||
|
|
@ -215,8 +215,7 @@ impl Config {
|
|||
xdg.and_then(|base| base.place_state_file("cosmic-comp/outputs.ron").ok());
|
||||
let outputs = Self::load_outputs(&output_path);
|
||||
|
||||
let input_path =
|
||||
xdg.and_then(|base| base.place_state_file("cosmic-comp/inputs.ron").ok());
|
||||
let input_path = xdg.and_then(|base| base.place_state_file("cosmic-comp/inputs.ron").ok());
|
||||
let inputs = Self::load_inputs(&input_path);
|
||||
|
||||
DynamicConfig {
|
||||
|
|
@ -244,7 +243,7 @@ impl Config {
|
|||
config: HashMap::new(),
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
fn load_inputs(path: &Option<PathBuf>) -> InputsConfig {
|
||||
if let Some(path) = path.as_ref() {
|
||||
if path.exists() {
|
||||
|
|
@ -265,10 +264,10 @@ impl Config {
|
|||
devices: HashMap::new(),
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
pub fn read_outputs(
|
||||
&mut self,
|
||||
outputs: impl Iterator<Item=impl std::borrow::Borrow<Output>>,
|
||||
outputs: impl Iterator<Item = impl std::borrow::Borrow<Output>>,
|
||||
backend: &mut BackendData,
|
||||
shell: &mut Shell,
|
||||
) {
|
||||
|
|
@ -295,11 +294,7 @@ impl Config {
|
|||
|
||||
for (name, output_config) in infos.iter().map(|o| &o.connector).zip(configs.into_iter())
|
||||
{
|
||||
let output = outputs
|
||||
.iter()
|
||||
.find(|o| &o.name() == name)
|
||||
.unwrap()
|
||||
.clone();
|
||||
let output = outputs.iter().find(|o| &o.name() == name).unwrap().clone();
|
||||
*output
|
||||
.user_data()
|
||||
.get::<RefCell<OutputConfig>>()
|
||||
|
|
@ -327,8 +322,7 @@ impl Config {
|
|||
.get::<RefCell<OutputConfig>>()
|
||||
.unwrap()
|
||||
.borrow_mut() = output_config;
|
||||
if let Err(err) = backend.apply_config_for_output(&output, false, shell)
|
||||
{
|
||||
if let Err(err) = backend.apply_config_for_output(&output, false, shell) {
|
||||
slog_scope::error!(
|
||||
"Failed to reset config for output {}: {}",
|
||||
output.name(),
|
||||
|
|
@ -339,8 +333,11 @@ impl Config {
|
|||
}
|
||||
}
|
||||
}
|
||||
|
||||
pub fn write_outputs(&mut self, outputs: impl Iterator<Item=impl std::borrow::Borrow<Output>>) {
|
||||
|
||||
pub fn write_outputs(
|
||||
&mut self,
|
||||
outputs: impl Iterator<Item = impl std::borrow::Borrow<Output>>,
|
||||
) {
|
||||
let mut infos = outputs
|
||||
.map(|o| {
|
||||
let o = o.borrow();
|
||||
|
|
@ -356,8 +353,7 @@ impl Config {
|
|||
.collect::<Vec<(OutputInfo, OutputConfig)>>();
|
||||
infos.sort_by(|&(ref a, _), &(ref b, _)| a.cmp(b));
|
||||
let (infos, configs) = infos.into_iter().unzip();
|
||||
self
|
||||
.dynamic_conf
|
||||
self.dynamic_conf
|
||||
.outputs_mut()
|
||||
.config
|
||||
.insert(infos, configs);
|
||||
|
|
@ -371,86 +367,168 @@ impl Config {
|
|||
Entry::Occupied(entry) => {
|
||||
let config = entry.get();
|
||||
if let Err(err) = match config.state {
|
||||
DeviceState::Enabled => device.config_send_events_set_mode(SendEventsMode::ENABLED),
|
||||
DeviceState::Disabled => device.config_send_events_set_mode(SendEventsMode::DISABLED),
|
||||
DeviceState::DisabledOnExternalMouse => device.config_send_events_set_mode(SendEventsMode::DISABLED_ON_EXTERNAL_MOUSE),
|
||||
DeviceState::Enabled => {
|
||||
device.config_send_events_set_mode(SendEventsMode::ENABLED)
|
||||
}
|
||||
DeviceState::Disabled => {
|
||||
device.config_send_events_set_mode(SendEventsMode::DISABLED)
|
||||
}
|
||||
DeviceState::DisabledOnExternalMouse => device
|
||||
.config_send_events_set_mode(SendEventsMode::DISABLED_ON_EXTERNAL_MOUSE),
|
||||
} {
|
||||
slog_scope::warn!("Failed to apply mode {:?} for device {:?}: {:?}", config.state, device.name(), err);
|
||||
slog_scope::warn!(
|
||||
"Failed to apply mode {:?} for device {:?}: {:?}",
|
||||
config.state,
|
||||
device.name(),
|
||||
err
|
||||
);
|
||||
}
|
||||
if let Some(accel) = config.acceleration.as_ref() {
|
||||
if let Some(profile) = accel.profile {
|
||||
if let Err(err) = device.config_accel_set_profile(profile) {
|
||||
slog_scope::warn!("Failed to apply acceleration profile {:?} for device {:?}: {:?}", profile, device.name(), err);
|
||||
slog_scope::warn!(
|
||||
"Failed to apply acceleration profile {:?} for device {:?}: {:?}",
|
||||
profile,
|
||||
device.name(),
|
||||
err
|
||||
);
|
||||
}
|
||||
}
|
||||
if let Err(err) = device.config_accel_set_speed(accel.speed) {
|
||||
slog_scope::warn!("Failed to apply acceleration speed {:?} for device {:?}: {:?}", accel.speed, device.name(), err);
|
||||
slog_scope::warn!(
|
||||
"Failed to apply acceleration speed {:?} for device {:?}: {:?}",
|
||||
accel.speed,
|
||||
device.name(),
|
||||
err
|
||||
);
|
||||
}
|
||||
}
|
||||
if let Some(matrix) = config.calibration {
|
||||
if let Err(err) = device.config_calibration_set_matrix(matrix) {
|
||||
slog_scope::warn!("Failed to apply calibration matrix {:?} for device {:?}: {:?}", matrix, device.name(), err);
|
||||
slog_scope::warn!(
|
||||
"Failed to apply calibration matrix {:?} for device {:?}: {:?}",
|
||||
matrix,
|
||||
device.name(),
|
||||
err
|
||||
);
|
||||
}
|
||||
}
|
||||
if let Some(dwt) = config.disable_while_typing {
|
||||
if let Err(err) = device.config_dwt_set_enabled(dwt) {
|
||||
slog_scope::warn!("Failed to apply disable-while-typing {:?} for device {:?}: {:?}", dwt, device.name(), err);
|
||||
slog_scope::warn!(
|
||||
"Failed to apply disable-while-typing {:?} for device {:?}: {:?}",
|
||||
dwt,
|
||||
device.name(),
|
||||
err
|
||||
);
|
||||
}
|
||||
}
|
||||
if let Some(left) = config.left_handed {
|
||||
if let Err(err) = device.config_left_handed_set(left) {
|
||||
slog_scope::warn!("Failed to apply left-handed {:?} for device {:?}: {:?}", left, device.name(), err);
|
||||
slog_scope::warn!(
|
||||
"Failed to apply left-handed {:?} for device {:?}: {:?}",
|
||||
left,
|
||||
device.name(),
|
||||
err
|
||||
);
|
||||
}
|
||||
}
|
||||
if let Some(middle) = config.middle_button_emulation {
|
||||
if let Err(err) = device.config_middle_emulation_set_enabled(middle) {
|
||||
slog_scope::warn!("Failed to apply middle-button-emulation {:?} for device {:?}: {:?}", middle, device.name(), err);
|
||||
slog_scope::warn!(
|
||||
"Failed to apply middle-button-emulation {:?} for device {:?}: {:?}",
|
||||
middle,
|
||||
device.name(),
|
||||
err
|
||||
);
|
||||
}
|
||||
}
|
||||
if let Some(angle) = config.rotation_angle {
|
||||
if let Err(err) = device.config_rotation_set_angle(angle) {
|
||||
slog_scope::warn!("Failed to apply rotation-angle {:?} for device {:?}: {:?}", angle, device.name(), err);
|
||||
slog_scope::warn!(
|
||||
"Failed to apply rotation-angle {:?} for device {:?}: {:?}",
|
||||
angle,
|
||||
device.name(),
|
||||
err
|
||||
);
|
||||
}
|
||||
}
|
||||
if let Some(scroll) = config.scroll_config.as_ref() {
|
||||
if let Some(method) = scroll.method {
|
||||
if let Err(err) = device.config_scroll_set_method(method) {
|
||||
slog_scope::warn!("Failed to apply scroll method {:?} for device {:?}: {:?}", method, device.name(), err);
|
||||
slog_scope::warn!(
|
||||
"Failed to apply scroll method {:?} for device {:?}: {:?}",
|
||||
method,
|
||||
device.name(),
|
||||
err
|
||||
);
|
||||
}
|
||||
}
|
||||
if let Some(natural) = scroll.natural_scroll {
|
||||
if let Err(err) = device.config_scroll_set_natural_scroll_enabled(natural) {
|
||||
slog_scope::warn!("Failed to apply natural scrolling {:?} for device {:?}: {:?}", natural, device.name(), err);
|
||||
slog_scope::warn!(
|
||||
"Failed to apply natural scrolling {:?} for device {:?}: {:?}",
|
||||
natural,
|
||||
device.name(),
|
||||
err
|
||||
);
|
||||
}
|
||||
}
|
||||
if let Some(button) = scroll.scroll_button {
|
||||
if let Err(err) = device.config_scroll_set_button(button) {
|
||||
slog_scope::warn!("Failed to apply scroll button {:?} for device {:?}: {:?}", button, device.name(), err);
|
||||
slog_scope::warn!(
|
||||
"Failed to apply scroll button {:?} for device {:?}: {:?}",
|
||||
button,
|
||||
device.name(),
|
||||
err
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
if let Some(tap) = config.tap_config.as_ref() {
|
||||
if let Err(err) = device.config_tap_set_enabled(tap.enabled) {
|
||||
slog_scope::warn!("Failed to apply tap-to-click {:?} for device {:?}: {:?}", tap.enabled, device.name(), err);
|
||||
slog_scope::warn!(
|
||||
"Failed to apply tap-to-click {:?} for device {:?}: {:?}",
|
||||
tap.enabled,
|
||||
device.name(),
|
||||
err
|
||||
);
|
||||
}
|
||||
if let Some(button_map) = tap.button_map {
|
||||
if let Err(err) = device.config_tap_set_button_map(button_map) {
|
||||
slog_scope::warn!("Failed to apply button map {:?} for device {:?}: {:?}", button_map, device.name(), err);
|
||||
slog_scope::warn!(
|
||||
"Failed to apply button map {:?} for device {:?}: {:?}",
|
||||
button_map,
|
||||
device.name(),
|
||||
err
|
||||
);
|
||||
}
|
||||
}
|
||||
if let Err(err) = device.config_tap_set_drag_enabled(tap.drag) {
|
||||
slog_scope::warn!("Failed to apply tap-drag {:?} for device {:?}: {:?}", tap.drag, device.name(), err);
|
||||
slog_scope::warn!(
|
||||
"Failed to apply tap-drag {:?} for device {:?}: {:?}",
|
||||
tap.drag,
|
||||
device.name(),
|
||||
err
|
||||
);
|
||||
}
|
||||
if let Err(err) = device.config_tap_set_drag_lock_enabled(tap.drag_lock) {
|
||||
slog_scope::warn!("Failed to apply tap-drag-lock {:?} for device {:?}: {:?}", tap.drag_lock, device.name(), err);
|
||||
slog_scope::warn!(
|
||||
"Failed to apply tap-drag-lock {:?} for device {:?}: {:?}",
|
||||
tap.drag_lock,
|
||||
device.name(),
|
||||
err
|
||||
);
|
||||
}
|
||||
}
|
||||
},
|
||||
}
|
||||
Entry::Vacant(entry) => {
|
||||
entry.insert(InputConfig {
|
||||
state: match device.config_send_events_mode() {
|
||||
x if x.contains(SendEventsMode::ENABLED) => DeviceState::Enabled,
|
||||
x if x.contains(SendEventsMode::DISABLED_ON_EXTERNAL_MOUSE) => DeviceState::DisabledOnExternalMouse,
|
||||
x if x.contains(SendEventsMode::DISABLED_ON_EXTERNAL_MOUSE) => {
|
||||
DeviceState::DisabledOnExternalMouse
|
||||
}
|
||||
x if x.contains(SendEventsMode::DISABLED) => DeviceState::Disabled,
|
||||
_ => DeviceState::Disabled,
|
||||
},
|
||||
|
|
@ -459,7 +537,9 @@ impl Config {
|
|||
profile: device.config_accel_profile(),
|
||||
speed: device.config_accel_speed(),
|
||||
})
|
||||
} else { None },
|
||||
} else {
|
||||
None
|
||||
},
|
||||
calibration: device.config_calibration_matrix(),
|
||||
click_method: device.config_click_method(),
|
||||
disable_while_typing: if device.config_dwt_is_available() {
|
||||
|
|
@ -482,7 +562,11 @@ impl Config {
|
|||
} else {
|
||||
None
|
||||
},
|
||||
scroll_config: if device.config_scroll_methods().iter().any(|x| *x != ScrollMethod::NoScroll) {
|
||||
scroll_config: if device
|
||||
.config_scroll_methods()
|
||||
.iter()
|
||||
.any(|x| *x != ScrollMethod::NoScroll)
|
||||
{
|
||||
Some(ScrollConfig {
|
||||
method: device.config_scroll_method(),
|
||||
natural_scroll: if device.config_scroll_has_natural_scroll() {
|
||||
|
|
@ -490,13 +574,17 @@ impl Config {
|
|||
} else {
|
||||
None
|
||||
},
|
||||
scroll_button: if device.config_scroll_method() == Some(ScrollMethod::OnButtonDown) {
|
||||
scroll_button: if device.config_scroll_method()
|
||||
== Some(ScrollMethod::OnButtonDown)
|
||||
{
|
||||
Some(device.config_scroll_button())
|
||||
} else {
|
||||
None
|
||||
},
|
||||
})
|
||||
} else { None },
|
||||
} else {
|
||||
None
|
||||
},
|
||||
tap_config: if device.config_tap_finger_count() > 0 {
|
||||
Some(TapConfig {
|
||||
enabled: device.config_tap_enabled(),
|
||||
|
|
@ -504,9 +592,11 @@ impl Config {
|
|||
drag: device.config_tap_drag_enabled(),
|
||||
drag_lock: device.config_tap_drag_lock_enabled(),
|
||||
})
|
||||
} else { None },
|
||||
} else {
|
||||
None
|
||||
},
|
||||
});
|
||||
},
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -556,7 +646,7 @@ impl DynamicConfig {
|
|||
pub fn outputs_mut<'a>(&'a mut self) -> PersistenceGuard<'a, OutputsConfig> {
|
||||
PersistenceGuard(self.outputs.0.clone(), &mut self.outputs.1)
|
||||
}
|
||||
|
||||
|
||||
pub fn inputs(&self) -> &InputsConfig {
|
||||
&self.inputs.1
|
||||
}
|
||||
|
|
|
|||
|
|
@ -36,8 +36,8 @@ impl Default for XkbConfig {
|
|||
}
|
||||
|
||||
pub mod ClickMethodDef {
|
||||
use serde::{Deserialize, Deserializer, Serialize, Serializer};
|
||||
use smithay::reexports::input::ClickMethod as ClickMethodOrig;
|
||||
use serde::{Deserialize, Serialize, Deserializer, Serializer};
|
||||
|
||||
#[derive(Debug, Serialize, Deserialize)]
|
||||
pub enum ClickMethod {
|
||||
|
|
@ -53,12 +53,12 @@ pub mod ClickMethodDef {
|
|||
Ok(o.map(|x| match x {
|
||||
ClickMethod::ButtonAreas => ClickMethodOrig::ButtonAreas,
|
||||
ClickMethod::Clickfinger => ClickMethodOrig::Clickfinger,
|
||||
}))
|
||||
}))
|
||||
}
|
||||
|
||||
|
||||
pub fn serialize<S>(arg: &Option<ClickMethodOrig>, ser: S) -> Result<S::Ok, S::Error>
|
||||
where
|
||||
S: Serializer
|
||||
S: Serializer,
|
||||
{
|
||||
let arg = match arg {
|
||||
Some(ClickMethodOrig::ButtonAreas) => Some(ClickMethod::ButtonAreas),
|
||||
|
|
@ -70,8 +70,8 @@ pub mod ClickMethodDef {
|
|||
}
|
||||
|
||||
pub mod AccelProfileDef {
|
||||
use serde::{Deserialize, Deserializer, Serialize, Serializer};
|
||||
use smithay::reexports::input::AccelProfile as AccelProfileOrig;
|
||||
use serde::{Deserialize, Serialize, Deserializer, Serializer};
|
||||
|
||||
#[derive(Debug, Serialize, Deserialize)]
|
||||
enum AccelProfile {
|
||||
|
|
@ -87,12 +87,12 @@ pub mod AccelProfileDef {
|
|||
Ok(o.map(|x| match x {
|
||||
AccelProfile::Flat => AccelProfileOrig::Flat,
|
||||
AccelProfile::Adaptive => AccelProfileOrig::Adaptive,
|
||||
}))
|
||||
}))
|
||||
}
|
||||
|
||||
|
||||
pub fn serialize<S>(arg: &Option<AccelProfileOrig>, ser: S) -> Result<S::Ok, S::Error>
|
||||
where
|
||||
S: Serializer
|
||||
S: Serializer,
|
||||
{
|
||||
let arg = match arg {
|
||||
Some(AccelProfileOrig::Flat) => Some(AccelProfile::Flat),
|
||||
|
|
@ -104,8 +104,8 @@ pub mod AccelProfileDef {
|
|||
}
|
||||
|
||||
pub mod ScrollMethodDef {
|
||||
use serde::{Deserialize, Deserializer, Serialize, Serializer};
|
||||
use smithay::reexports::input::ScrollMethod as ScrollMethodOrig;
|
||||
use serde::{Deserialize, Serialize, Deserializer, Serializer};
|
||||
|
||||
#[derive(Debug, Serialize, Deserialize)]
|
||||
pub enum ScrollMethod {
|
||||
|
|
@ -125,12 +125,12 @@ pub mod ScrollMethodDef {
|
|||
ScrollMethod::TwoFinger => ScrollMethodOrig::TwoFinger,
|
||||
ScrollMethod::Edge => ScrollMethodOrig::Edge,
|
||||
ScrollMethod::OnButtonDown => ScrollMethodOrig::OnButtonDown,
|
||||
}))
|
||||
}))
|
||||
}
|
||||
|
||||
|
||||
pub fn serialize<S>(arg: &Option<ScrollMethodOrig>, ser: S) -> Result<S::Ok, S::Error>
|
||||
where
|
||||
S: Serializer
|
||||
S: Serializer,
|
||||
{
|
||||
let arg = match arg {
|
||||
Some(ScrollMethodOrig::NoScroll) => Some(ScrollMethod::NoScroll),
|
||||
|
|
@ -157,8 +157,8 @@ pub enum TransformDef {
|
|||
}
|
||||
|
||||
pub mod TapButtonMapDef {
|
||||
use serde::{Deserialize, Deserializer, Serialize, Serializer};
|
||||
use smithay::reexports::input::TapButtonMap as TapButtonMapOrig;
|
||||
use serde::{Deserialize, Serialize, Deserializer, Serializer};
|
||||
|
||||
#[derive(Debug, Serialize, Deserialize)]
|
||||
pub enum TapButtonMap {
|
||||
|
|
@ -174,12 +174,12 @@ pub mod TapButtonMapDef {
|
|||
Ok(o.map(|x| match x {
|
||||
TapButtonMap::LeftRightMiddle => TapButtonMapOrig::LeftRightMiddle,
|
||||
TapButtonMap::LeftMiddleRight => TapButtonMapOrig::LeftMiddleRight,
|
||||
}))
|
||||
}))
|
||||
}
|
||||
|
||||
|
||||
pub fn serialize<S>(arg: &Option<TapButtonMapOrig>, ser: S) -> Result<S::Ok, S::Error>
|
||||
where
|
||||
S: Serializer
|
||||
S: Serializer,
|
||||
{
|
||||
let arg = match arg {
|
||||
Some(TapButtonMapOrig::LeftRightMiddle) => Some(TapButtonMap::LeftRightMiddle),
|
||||
|
|
@ -248,4 +248,3 @@ where
|
|||
x => Ok(x),
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
136
src/input/mod.rs
136
src/input/mod.rs
|
|
@ -1,6 +1,10 @@
|
|||
// SPDX-License-Identifier: GPL-3.0-only
|
||||
|
||||
use crate::{config::Action, state::{Common, State}, shell::Workspace};
|
||||
use crate::{
|
||||
config::Action,
|
||||
shell::Workspace,
|
||||
state::{Common, State},
|
||||
};
|
||||
use smithay::{
|
||||
backend::input::{Device, DeviceCapability, InputBackend, InputEvent, KeyState},
|
||||
desktop::{layer_map_for_output, Kind, Space, WindowSurfaceType},
|
||||
|
|
@ -9,13 +13,13 @@ use smithay::{
|
|||
wayland::{
|
||||
data_device::set_data_device_focus,
|
||||
output::Output,
|
||||
seat::{CursorImageStatus, FilterResult, KeysymHandle, Seat, XkbConfig, keysyms},
|
||||
seat::{keysyms, CursorImageStatus, FilterResult, KeysymHandle, Seat, XkbConfig},
|
||||
shell::wlr_layer::Layer as WlrLayer,
|
||||
SERIAL_COUNTER,
|
||||
},
|
||||
};
|
||||
use xkbcommon::xkb::KEY_XF86Switch_VT_12;
|
||||
use std::{cell::RefCell, collections::HashMap};
|
||||
use xkbcommon::xkb::KEY_XF86Switch_VT_12;
|
||||
|
||||
pub struct ActiveOutput(pub RefCell<Output>);
|
||||
pub struct SupressedKeys(RefCell<Vec<u32>>);
|
||||
|
|
@ -214,7 +218,8 @@ impl State {
|
|||
|
||||
#[cfg(feature = "debug")]
|
||||
{
|
||||
if self.common.seats.iter().position(|x| x == seat).unwrap() == 0
|
||||
if self.common.seats.iter().position(|x| x == seat).unwrap()
|
||||
== 0
|
||||
&& self.common.egui.active
|
||||
{
|
||||
if self.common.egui.debug_state.wants_keyboard() {
|
||||
|
|
@ -238,16 +243,26 @@ impl State {
|
|||
}
|
||||
}
|
||||
|
||||
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);
|
||||
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()
|
||||
for (binding, action) in
|
||||
self.common.config.static_conf.key_bindings.iter()
|
||||
{
|
||||
if state == KeyState::Pressed
|
||||
&& binding.modifiers == *modifiers
|
||||
|
|
@ -276,7 +291,8 @@ impl State {
|
|||
}
|
||||
Action::Close => {
|
||||
let current_output = active_output(seat, &self.common);
|
||||
let workspace = self.common.shell.active_space_mut(¤t_output);
|
||||
let workspace =
|
||||
self.common.shell.active_space_mut(¤t_output);
|
||||
if let Some(window) = workspace.focus_stack(seat).last() {
|
||||
#[allow(irrefutable_let_patterns)]
|
||||
if let Kind::Xdg(xdg) = &window.toplevel() {
|
||||
|
|
@ -290,8 +306,11 @@ impl State {
|
|||
0 => 9,
|
||||
x => x - 1,
|
||||
};
|
||||
self.common.shell
|
||||
.activate(seat, ¤t_output, workspace as usize);
|
||||
self.common.shell.activate(
|
||||
seat,
|
||||
¤t_output,
|
||||
workspace as usize,
|
||||
);
|
||||
}
|
||||
Action::MoveToWorkspace(key_num) => {
|
||||
let current_output = active_output(seat, &self.common);
|
||||
|
|
@ -316,7 +335,8 @@ impl State {
|
|||
}
|
||||
Action::Fullscreen => {
|
||||
let current_output = active_output(seat, &self.common);
|
||||
let workspace = self.common.shell.active_space_mut(¤t_output);
|
||||
let workspace =
|
||||
self.common.shell.active_space_mut(¤t_output);
|
||||
let focused_window = workspace.focus_stack(seat).last();
|
||||
if let Some(window) = focused_window {
|
||||
workspace.fullscreen_toggle(&window, ¤t_output);
|
||||
|
|
@ -324,7 +344,9 @@ impl State {
|
|||
}
|
||||
Action::Orientation(orientation) => {
|
||||
let output = active_output(seat, &self.common);
|
||||
self.common.shell.set_orientation(&seat, &output, *orientation);
|
||||
self.common
|
||||
.shell
|
||||
.set_orientation(&seat, &output, *orientation);
|
||||
}
|
||||
Action::Spawn(command) => {
|
||||
if let Err(err) = std::process::Command::new("/bin/sh")
|
||||
|
|
@ -381,8 +403,10 @@ impl State {
|
|||
.min((output_geometry.loc.y + output_geometry.size.h) as f64);
|
||||
|
||||
let serial = SERIAL_COUNTER.next_serial();
|
||||
let relative_pos =
|
||||
self.common.shell.space_relative_output_geometry(position, &output);
|
||||
let relative_pos = self
|
||||
.common
|
||||
.shell
|
||||
.space_relative_output_geometry(position, &output);
|
||||
let workspace = self.common.shell.active_space_mut(&output);
|
||||
let under = State::surface_under(
|
||||
position,
|
||||
|
|
@ -401,10 +425,12 @@ impl State {
|
|||
|
||||
#[cfg(feature = "debug")]
|
||||
if self.common.seats.iter().position(|x| x == seat).unwrap() == 0 {
|
||||
self.common.egui
|
||||
self.common
|
||||
.egui
|
||||
.debug_state
|
||||
.handle_pointer_motion(position.to_i32_round());
|
||||
self.common.egui
|
||||
self.common
|
||||
.egui
|
||||
.log_state
|
||||
.handle_pointer_motion(position.to_i32_round());
|
||||
}
|
||||
|
|
@ -424,8 +450,10 @@ impl State {
|
|||
let geometry = self.common.shell.output_geometry(&output);
|
||||
let position =
|
||||
geometry.loc.to_f64() + event.position_transformed(geometry.size);
|
||||
let relative_pos =
|
||||
self.common.shell.space_relative_output_geometry(position, &output);
|
||||
let relative_pos = self
|
||||
.common
|
||||
.shell
|
||||
.space_relative_output_geometry(position, &output);
|
||||
let workspace = self.common.shell.active_space_mut(&output);
|
||||
let serial = SERIAL_COUNTER.next_serial();
|
||||
let under = State::surface_under(
|
||||
|
|
@ -445,10 +473,12 @@ impl State {
|
|||
|
||||
#[cfg(feature = "debug")]
|
||||
if self.common.seats.iter().position(|x| x == seat).unwrap() == 0 {
|
||||
self.common.egui
|
||||
self.common
|
||||
.egui
|
||||
.debug_state
|
||||
.handle_pointer_motion(position.to_i32_round());
|
||||
self.common.egui
|
||||
self.common
|
||||
.egui
|
||||
.log_state
|
||||
.handle_pointer_motion(position.to_i32_round());
|
||||
}
|
||||
|
|
@ -502,15 +532,17 @@ impl State {
|
|||
let output = active_output(seat, &self.common);
|
||||
let pos = seat.get_pointer().unwrap().current_location();
|
||||
let output_geo = self.common.shell.output_geometry(&output);
|
||||
let relative_pos =
|
||||
self.common.shell.space_relative_output_geometry(pos, &output);
|
||||
let relative_pos = self
|
||||
.common
|
||||
.shell
|
||||
.space_relative_output_geometry(pos, &output);
|
||||
let workspace = self.common.shell.active_space_mut(&output);
|
||||
let layers = layer_map_for_output(&output);
|
||||
let mut under = None;
|
||||
|
||||
if let Some(window) = workspace.get_fullscreen(&output) {
|
||||
if let Some(layer) = layers
|
||||
.layer_under(WlrLayer::Overlay, relative_pos)
|
||||
if let Some(layer) =
|
||||
layers.layer_under(WlrLayer::Overlay, relative_pos)
|
||||
{
|
||||
if layer.can_receive_keyboard_focus() {
|
||||
let layer_loc =
|
||||
|
|
@ -523,17 +555,21 @@ impl State {
|
|||
)
|
||||
.map(|(s, _)| s);
|
||||
}
|
||||
} else {
|
||||
under = window.surface_under(
|
||||
pos - output_geo.loc.to_f64(),
|
||||
WindowSurfaceType::TOPLEVEL
|
||||
| WindowSurfaceType::SUBSURFACE
|
||||
).map(|(s, _)| s);
|
||||
} else {
|
||||
under = window
|
||||
.surface_under(
|
||||
pos - output_geo.loc.to_f64(),
|
||||
WindowSurfaceType::TOPLEVEL
|
||||
| WindowSurfaceType::SUBSURFACE,
|
||||
)
|
||||
.map(|(s, _)| s);
|
||||
}
|
||||
} else {
|
||||
if let Some(layer) = layers
|
||||
.layer_under(WlrLayer::Overlay, relative_pos)
|
||||
.or_else(|| layers.layer_under(WlrLayer::Top, relative_pos))
|
||||
.or_else(|| {
|
||||
layers.layer_under(WlrLayer::Top, relative_pos)
|
||||
})
|
||||
{
|
||||
if layer.can_receive_keyboard_focus() {
|
||||
let layer_loc =
|
||||
|
|
@ -547,12 +583,17 @@ impl State {
|
|||
.map(|(s, _)| s);
|
||||
}
|
||||
} else if let Some((_, surface, _)) =
|
||||
workspace.space.surface_under(relative_pos, WindowSurfaceType::TOPLEVEL | WindowSurfaceType::SUBSURFACE)
|
||||
workspace.space.surface_under(
|
||||
relative_pos,
|
||||
WindowSurfaceType::TOPLEVEL
|
||||
| WindowSurfaceType::SUBSURFACE,
|
||||
)
|
||||
{
|
||||
under = Some(surface);
|
||||
} else if let Some(layer) = layers
|
||||
.layer_under(WlrLayer::Bottom, pos)
|
||||
.or_else(|| layers.layer_under(WlrLayer::Background, pos))
|
||||
} 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 =
|
||||
|
|
@ -591,7 +632,9 @@ impl State {
|
|||
let device = event.device();
|
||||
for seat in self.common.seats.clone().iter() {
|
||||
#[cfg(feature = "debug")]
|
||||
if self.common.seats.iter().position(|x| x == seat).unwrap() == 0 && self.common.egui.active {
|
||||
if self.common.seats.iter().position(|x| x == seat).unwrap() == 0
|
||||
&& self.common.egui.active
|
||||
{
|
||||
if self.common.egui.debug_state.wants_pointer() {
|
||||
self.common.egui.debug_state.handle_pointer_axis(
|
||||
event
|
||||
|
|
@ -696,15 +739,10 @@ impl State {
|
|||
WindowSurfaceType::ALL,
|
||||
)
|
||||
.map(|(s, loc)| (s, loc + layer_loc + output_geo.loc))
|
||||
} else {
|
||||
} else {
|
||||
window
|
||||
.surface_under(global_pos - output_geo.loc.to_f64(), WindowSurfaceType::ALL)
|
||||
.map(|(s, loc)| {
|
||||
(
|
||||
s,
|
||||
loc + output_geo.loc,
|
||||
)
|
||||
})
|
||||
.map(|(s, loc)| (s, loc + output_geo.loc))
|
||||
}
|
||||
} else {
|
||||
if let Some(layer) = layers
|
||||
|
|
@ -718,11 +756,11 @@ impl State {
|
|||
WindowSurfaceType::ALL,
|
||||
)
|
||||
.map(|(s, loc)| (s, loc + layer_loc + output_geo.loc))
|
||||
} else if let Some((_, surface, loc)) = workspace.space.surface_under(relative_pos, WindowSurfaceType::ALL) {
|
||||
Some((
|
||||
surface,
|
||||
loc + (global_pos - relative_pos).to_i32_round(),
|
||||
))
|
||||
} else if let Some((_, surface, loc)) = workspace
|
||||
.space
|
||||
.surface_under(relative_pos, WindowSurfaceType::ALL)
|
||||
{
|
||||
Some((surface, loc + (global_pos - relative_pos).to_i32_round()))
|
||||
} else if let Some(layer) = layers
|
||||
.layer_under(WlrLayer::Bottom, relative_pos)
|
||||
.or_else(|| layers.layer_under(WlrLayer::Background, relative_pos))
|
||||
|
|
|
|||
|
|
@ -31,7 +31,13 @@ fn main() -> Result<()> {
|
|||
// init wayland
|
||||
let (display, socket) = init_wayland_display(&mut event_loop)?;
|
||||
// init state
|
||||
let mut state = state::State::new(display, socket, event_loop.handle(), event_loop.get_signal(), log);
|
||||
let mut state = state::State::new(
|
||||
display,
|
||||
socket,
|
||||
event_loop.handle(),
|
||||
event_loop.get_signal(),
|
||||
log,
|
||||
);
|
||||
// init backend
|
||||
backend::init_backend_auto(&mut event_loop, &mut state)?;
|
||||
// potentially tell systemd we are setup now
|
||||
|
|
|
|||
|
|
@ -16,9 +16,7 @@ use smithay::{
|
|||
output::Output,
|
||||
seat::{PointerGrabStartData, Seat},
|
||||
shell::{
|
||||
wlr_layer::{
|
||||
wlr_layer_shell_init, LayerShellRequest, LayerSurfaceAttributes,
|
||||
},
|
||||
wlr_layer::{wlr_layer_shell_init, LayerShellRequest, LayerSurfaceAttributes},
|
||||
xdg::{
|
||||
xdg_shell_init, Configure, XdgPopupSurfaceRoleAttributes, XdgRequest,
|
||||
XdgToplevelSurfaceRoleAttributes,
|
||||
|
|
@ -259,7 +257,11 @@ pub fn init_shell(config: &Config, display: &mut Display) -> super::Shell {
|
|||
.as_ref()
|
||||
.and_then(Output::from_resource)
|
||||
.unwrap_or_else(|| active_output(&seat, &*state));
|
||||
state.shell.active_space_mut(&output).pending_layer(LayerSurface::new(surface, namespace), &output, &seat);
|
||||
state.shell.active_space_mut(&output).pending_layer(
|
||||
LayerSurface::new(surface, namespace),
|
||||
&output,
|
||||
&seat,
|
||||
);
|
||||
}
|
||||
_ => {}
|
||||
},
|
||||
|
|
|
|||
|
|
@ -85,7 +85,10 @@ impl Layout for TilingLayout {
|
|||
focus_stack: Box<dyn Iterator<Item = &'a Window> + 'a>,
|
||||
) -> Option<Window> {
|
||||
let output = super::output_from_seat(Some(seat), space);
|
||||
let idx = space.outputs().position(|o| Some(o) == output.as_ref()).unwrap_or(0);
|
||||
let idx = space
|
||||
.outputs()
|
||||
.position(|o| Some(o) == output.as_ref())
|
||||
.unwrap_or(0);
|
||||
let tree = TilingLayout::active_tree(&mut self.trees, idx);
|
||||
if let Some(last_active) = TilingLayout::last_active_window(tree, focus_stack) {
|
||||
let mut node_id = last_active;
|
||||
|
|
@ -141,7 +144,10 @@ impl Layout for TilingLayout {
|
|||
focus_stack: Box<dyn Iterator<Item = &'a Window> + 'a>,
|
||||
) {
|
||||
let output = super::output_from_seat(Some(seat), space);
|
||||
let idx = space.outputs().position(|o| Some(o) == output.as_ref()).unwrap_or(0);
|
||||
let idx = space
|
||||
.outputs()
|
||||
.position(|o| Some(o) == output.as_ref())
|
||||
.unwrap_or(0);
|
||||
let tree = TilingLayout::active_tree(&mut self.trees, idx);
|
||||
if let Some(last_active) = TilingLayout::last_active_window(tree, focus_stack) {
|
||||
if let Some((fork, _child)) = TilingLayout::find_fork(tree, last_active) {
|
||||
|
|
@ -288,7 +294,10 @@ impl TilingLayout {
|
|||
focus_stack: Option<Box<dyn Iterator<Item = &'a Window> + 'a>>,
|
||||
) {
|
||||
let output = super::output_from_seat(seat, space);
|
||||
let idx = space.outputs().position(|o| Some(o) == output.as_ref()).unwrap_or(0);
|
||||
let idx = space
|
||||
.outputs()
|
||||
.position(|o| Some(o) == output.as_ref())
|
||||
.unwrap_or(0);
|
||||
let tree = TilingLayout::active_tree(&mut self.trees, idx);
|
||||
let new_window = Node::new(Data::Window(window.clone()));
|
||||
|
||||
|
|
@ -529,8 +538,18 @@ impl TilingLayout {
|
|||
if let Some(geo) = geo {
|
||||
#[allow(irrefutable_let_patterns)]
|
||||
if let Kind::Xdg(xdg) = &window.toplevel() {
|
||||
if xdg.current_state().map(|state| state.states.contains(XdgState::Fullscreen)).unwrap_or(false) ||
|
||||
xdg.with_pending_state(|pending| pending.states.contains(XdgState::Fullscreen)).unwrap_or(false) {
|
||||
if xdg
|
||||
.current_state()
|
||||
.map(|state| {
|
||||
state.states.contains(XdgState::Fullscreen)
|
||||
})
|
||||
.unwrap_or(false)
|
||||
|| xdg
|
||||
.with_pending_state(|pending| {
|
||||
pending.states.contains(XdgState::Fullscreen)
|
||||
})
|
||||
.unwrap_or(false)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
let ret = xdg.with_pending_state(|state| {
|
||||
|
|
@ -549,10 +568,7 @@ impl TilingLayout {
|
|||
}
|
||||
space.map_window(
|
||||
&window,
|
||||
(
|
||||
geo.loc.x + inner,
|
||||
geo.loc.y + inner,
|
||||
),
|
||||
(geo.loc.x + inner, geo.loc.y + inner),
|
||||
false,
|
||||
);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -3,7 +3,7 @@ use super::{layout, Layout};
|
|||
use crate::wayland::workspace as ext_work;
|
||||
use indexmap::IndexSet;
|
||||
use smithay::{
|
||||
desktop::{LayerSurface, Space, Window, Kind},
|
||||
desktop::{Kind, LayerSurface, Space, Window},
|
||||
reexports::wayland_protocols::xdg_shell::server::xdg_toplevel::{self, ResizeEdge},
|
||||
wayland::{
|
||||
output::Output,
|
||||
|
|
@ -61,9 +61,7 @@ pub struct Workspace {
|
|||
}
|
||||
|
||||
impl Workspace {
|
||||
pub fn new(
|
||||
idx: u8,
|
||||
) -> Workspace {
|
||||
pub fn new(idx: u8) -> Workspace {
|
||||
Workspace {
|
||||
idx,
|
||||
space: Space::new(None),
|
||||
|
|
@ -126,11 +124,10 @@ impl Workspace {
|
|||
|
||||
pub fn refresh(&mut self) {
|
||||
let outputs = self.space.outputs().collect::<Vec<_>>();
|
||||
let dead_output_windows = self.fullscreen
|
||||
let dead_output_windows = self
|
||||
.fullscreen
|
||||
.iter()
|
||||
.filter(|(name, _)|
|
||||
!outputs.iter().any(|o| o.name() == **name)
|
||||
)
|
||||
.filter(|(name, _)| !outputs.iter().any(|o| o.name() == **name))
|
||||
.map(|(_, w)| w)
|
||||
.cloned()
|
||||
.collect::<Vec<_>>();
|
||||
|
|
@ -235,7 +232,7 @@ impl Workspace {
|
|||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
pub fn unfullscreen_request(&mut self, window: &Window) {
|
||||
if self.fullscreen.values().any(|w| w == window) {
|
||||
#[allow(irrefutable_let_patterns)]
|
||||
|
|
@ -248,7 +245,7 @@ impl Workspace {
|
|||
if ret.is_ok() {
|
||||
self.layout.refresh(&mut self.space);
|
||||
xdg.send_configure();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
self.fullscreen.retain(|_, w| w != window);
|
||||
|
|
@ -267,6 +264,8 @@ impl Workspace {
|
|||
if !self.space.outputs().any(|o| o == output) {
|
||||
return None;
|
||||
}
|
||||
self.fullscreen.get(&output.name()).filter(|w| w.toplevel().get_surface().is_some())
|
||||
self.fullscreen
|
||||
.get(&output.name())
|
||||
.filter(|w| w.toplevel().get_surface().is_some())
|
||||
}
|
||||
}
|
||||
|
|
|
|||
10
src/state.rs
10
src/state.rs
|
|
@ -145,8 +145,8 @@ impl BackendData {
|
|||
});
|
||||
let transform =
|
||||
Some(final_config.transform.into()).filter(|x| *x != output.current_transform());
|
||||
let scale =
|
||||
Some(final_config.scale).filter(|x| *x != output.current_scale().fractional_scale());
|
||||
let scale = Some(final_config.scale)
|
||||
.filter(|x| *x != output.current_scale().fractional_scale());
|
||||
let location =
|
||||
Some(final_config.position.into()).filter(|x| *x != output.current_location());
|
||||
output.change_current_state(mode, transform, scale.map(Scale::Fractional), location);
|
||||
|
|
@ -295,7 +295,6 @@ impl State {
|
|||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
for output in conf.iter().filter(|(_, c)| c.is_some()).map(|(o, _)| o) {
|
||||
|
|
@ -304,7 +303,10 @@ impl State {
|
|||
for output in conf.iter().filter(|(_, c)| c.is_none()).map(|(o, _)| o) {
|
||||
wlr_configuration::disable_head(output);
|
||||
}
|
||||
state.common.config.write_outputs(state.common.output_conf.outputs());
|
||||
state
|
||||
.common
|
||||
.config
|
||||
.write_outputs(state.common.output_conf.outputs());
|
||||
state.common.event_loop_handle.insert_idle(move |state| {
|
||||
state
|
||||
.common
|
||||
|
|
|
|||
|
|
@ -1,8 +1,8 @@
|
|||
// SPDX-License-Identifier: GPL-3.0-only
|
||||
|
||||
use crate::state::State;
|
||||
use libsystemd::daemon::{booted, notify, NotifyState};
|
||||
use std::process::Command;
|
||||
use crate::state::State;
|
||||
|
||||
pub fn ready(state: &State) {
|
||||
if booted() {
|
||||
|
|
@ -11,13 +11,19 @@ pub fn ready(state: &State) {
|
|||
.env("WAYLAND_DISPLAY", &state.common.socket)
|
||||
.status()
|
||||
{
|
||||
Ok(x) if x.success() => {},
|
||||
Ok(x) => slog_scope::warn!("Failed to import WAYLAND_DISPLAY into systemd (exit code {:?})", x.code()),
|
||||
Err(err) => slog_scope::error!("Failed to run systemctl although booted with systemd: {}", err),
|
||||
Ok(x) if x.success() => {}
|
||||
Ok(x) => slog_scope::warn!(
|
||||
"Failed to import WAYLAND_DISPLAY into systemd (exit code {:?})",
|
||||
x.code()
|
||||
),
|
||||
Err(err) => slog_scope::error!(
|
||||
"Failed to run systemctl although booted with systemd: {}",
|
||||
err
|
||||
),
|
||||
};
|
||||
|
||||
if let Err(err) = notify(false, &[NotifyState::Ready]) {
|
||||
slog_scope::error!("Failed to notify systemd: {}", err);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue