Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

X11 backend #371

Merged
merged 5 commits into from
Oct 18, 2021
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -126,6 +126,7 @@ jobs:
- backend_session
- backend_session_logind
- backend_session_libseat
- backend_x11
- renderer_gl
- wayland_frontend
- xwayland
Expand Down Expand Up @@ -199,6 +200,7 @@ jobs:
- winit
- udev
- logind
- x11
- default
- test_all_features

Expand Down
8 changes: 8 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -25,13 +25,21 @@
- Support for `xdg_wm_base` protocol version 3
- Added the option to initialize the dmabuf global with a client filter

#### Backends

- New `x11` backend to run the compositor as an X11 client. Enabled through the `backend_x11` feature.
- `x11rb` event source integration used in anvil's XWayland implementation is now part of smithay at `utils::x11rb`. Enabled through the `x11rb_event_source` feature.
- `KeyState`, `MouseButton`, `ButtonState` and `Axis` in `backend::input` now derive `Hash`.
- New `DrmNode` type in drm backend. This is primarily for use a backend which needs to run as client inside another session.

### Bugfixes

- EGLBufferReader now checks if buffers are alive before using them.
- LibSeat no longer panics on seat disable event.

### Anvil

- Anvil now implements the x11 backend in smithay. Run by passing `--x11` into the arguments when launching.
- Passing `ANVIL_MUTEX_LOG` in environment variables now uses the slower `Mutex` logging drain.

## version 0.3.0 (2021-07-25)
Expand Down
7 changes: 5 additions & 2 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,7 @@ drm-ffi = { version = "0.2.0", optional = true }
gbm = { version = "0.7.0", optional = true, default-features = false, features = ["drm-support"] }
input = { version = "0.6", default-features = false, features=["libinput_1_14"], optional = true }
lazy_static = "1"
libc = "0.2.70"
libc = "0.2.103"
libseat= { version = "0.1.1", optional = true }
libloading = { version="0.7.0", optional = true }
nix = "0.22"
Expand All @@ -46,6 +46,7 @@ wayland-protocols = { version = "0.29.0", features = ["unstable_protocols", "sta
wayland-server = { version = "0.29.0", optional = true }
wayland-sys = { version = "0.29.0", optional = true }
winit = { version = "0.25.0", optional = true }
x11rb = { version = "0.9.0", optional = true }
xkbcommon = "0.4.0"
scan_fmt = { version = "0.2.3", default-features = false }

Expand All @@ -57,8 +58,9 @@ gl_generator = { version = "0.14", optional = true }
pkg-config = { version = "0.3.17", optional = true }

[features]
default = ["backend_drm", "backend_gbm", "backend_libinput", "backend_udev", "backend_session_logind", "backend_winit", "renderer_gl", "xwayland", "wayland_frontend", "slog-stdlog"]
default = ["backend_drm", "backend_gbm", "backend_libinput", "backend_udev", "backend_session_logind", "backend_winit", "renderer_gl", "xwayland", "wayland_frontend", "slog-stdlog", "backend_x11"]
backend_winit = ["winit", "wayland-server/dlopen", "backend_egl", "wayland-egl", "renderer_gl"]
backend_x11 = ["x11rb", "x11rb/dri3", "x11rb/xfixes", "x11rb/present", "x11rb_event_source", "backend_gbm", "backend_drm"]
backend_drm = ["drm", "drm-ffi"]
backend_gbm = ["gbm"]
backend_egl = ["gl_generator", "libloading"]
Expand All @@ -71,6 +73,7 @@ backend_session_libseat = ["backend_session", "libseat"]
renderer_gl = ["gl_generator", "backend_egl"]
use_system_lib = ["wayland_frontend", "wayland-sys", "wayland-server/use_system_lib"]
wayland_frontend = ["wayland-server", "wayland-commons", "wayland-protocols", "tempfile"]
x11rb_event_source = ["x11rb"]
xwayland = ["wayland_frontend"]
test_all_features = ["default", "use_system_lib", "wayland-server/dlopen"]

Expand Down
1 change: 1 addition & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,7 @@ cargo run -- --{backend}

The currently available backends are:

- `--x11`: start anvil as an X11 client. This allows you to run the compositor inside an X11 session or any compositor supporting XWayland. Should be preferred over the winit backend where possible.
- `--winit`: start anvil as a [Winit](https://github.com/tomaka/winit) application. This allows you to run it
inside of an other X11 or Wayland session.
- `--tty-udev`: start anvil in a tty with udev support. This is the "traditional" launch of a Wayland
Expand Down
7 changes: 4 additions & 3 deletions anvil/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -28,21 +28,22 @@ features = [ "wayland_frontend", "slog-stdlog" ]

[dependencies.x11rb]
optional = true
version = "0.8"
version = "0.9.0"
default-features = false
features = [ "composite" ]

[build-dependencies]
gl_generator = "0.14"

[features]
default = [ "winit", "udev", "logind", "egl", "xwayland" ]
default = [ "winit", "udev", "logind", "egl", "xwayland", "x11" ]
egl = [ "smithay/use_system_lib", "smithay/backend_egl" ]
winit = [ "smithay/backend_winit" ]
udev = [ "smithay/backend_libinput", "smithay/backend_udev", "smithay/backend_drm", "smithay/backend_gbm", "smithay/backend_egl", "smithay/backend_session", "input", "image", "smithay/renderer_gl", "xcursor" ]
logind = [ "smithay/backend_session_logind" ]
elogind = ["logind", "smithay/backend_session_elogind" ]
libseat = ["smithay/backend_session_libseat" ]
xwayland = [ "smithay/xwayland", "x11rb" ]
xwayland = [ "smithay/xwayland", "x11rb", "smithay/x11rb_event_source" ]
x11 = [ "smithay/backend_x11", "x11rb", "egl", "smithay/renderer_gl" ]
debug = [ "fps_ticker", "image/png" ]
test_all_features = ["default", "debug"]
88 changes: 86 additions & 2 deletions anvil/src/input_handler.rs
Original file line number Diff line number Diff line change
@@ -1,10 +1,13 @@
use std::{process::Command, sync::atomic::Ordering};

use crate::AnvilState;

#[cfg(feature = "udev")]
use crate::udev::UdevData;
#[cfg(feature = "winit")]
use crate::winit::WinitData;
use crate::AnvilState;
#[cfg(feature = "x11")]
use crate::x11::X11Data;

use smithay::{
backend::input::{
Expand All @@ -18,7 +21,7 @@ use smithay::{
},
};

#[cfg(feature = "winit")]
#[cfg(any(feature = "winit", feature = "x11"))]
use smithay::{backend::input::PointerMotionAbsoluteEvent, wayland::output::Mode};

#[cfg(feature = "udev")]
Expand Down Expand Up @@ -507,6 +510,87 @@ impl AnvilState<UdevData> {
}
}

#[cfg(feature = "x11")]
impl AnvilState<X11Data> {
pub fn process_input_event<B: InputBackend>(&mut self, event: InputEvent<B>) {
match event {
InputEvent::Keyboard { event } => match self.keyboard_key_to_action::<B>(event) {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I feel like this could have some deduplication wrt other backends

KeyAction::None => (),

KeyAction::Quit => {
info!(self.log, "Quitting.");
self.running.store(false, Ordering::SeqCst);
}

KeyAction::Run(cmd) => {
info!(self.log, "Starting program"; "cmd" => cmd.clone());

if let Err(e) = Command::new(&cmd).spawn() {
error!(self.log,
"Failed to start program";
"cmd" => cmd,
"err" => format!("{:?}", e)
);
}
}

KeyAction::ScaleUp => {
let current_scale = {
self.output_map
.borrow()
.find_by_name(crate::x11::OUTPUT_NAME)
.map(|o| o.scale())
.unwrap_or(1.0)
};

self.output_map
.borrow_mut()
.update_scale_by_name(current_scale + 0.25f32, crate::x11::OUTPUT_NAME);
}

KeyAction::ScaleDown => {
let current_scale = {
self.output_map
.borrow()
.find_by_name(crate::x11::OUTPUT_NAME)
.map(|o| o.scale())
.unwrap_or(1.0)
};

self.output_map.borrow_mut().update_scale_by_name(
f32::max(1.0f32, current_scale + 0.25f32),
crate::x11::OUTPUT_NAME,
);
}

action => {
warn!(self.log, "Key action {:?} unsupported on x11 backend.", action);
}
},

InputEvent::PointerMotionAbsolute { event } => self.on_pointer_move_absolute::<B>(event),
InputEvent::PointerButton { event } => self.on_pointer_button::<B>(event),
InputEvent::PointerAxis { event } => self.on_pointer_axis::<B>(event),
_ => (), // other events are not handled in anvil (yet)
}
}

fn on_pointer_move_absolute<B: InputBackend>(&mut self, evt: B::PointerMotionAbsoluteEvent) {
let output_size = self
.output_map
.borrow()
.find_by_name(crate::x11::OUTPUT_NAME)
.map(|o| o.size())
.unwrap();

let pos = evt.position_transformed(output_size);
self.pointer_location = pos;
let serial = SCOUNTER.next_serial();
let under = self.window_map.borrow().get_surface_under(pos);
self.pointer.motion(pos, under, serial, evt.time());
}
}

/// Possible results of a keyboard action
#[derive(Debug)]
enum KeyAction {
Expand Down
4 changes: 3 additions & 1 deletion anvil/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ pub mod cursor;
pub mod drawing;
pub mod input_handler;
pub mod output_map;
#[cfg(any(feature = "udev", feature = "winit"))]
#[cfg(any(feature = "udev", feature = "winit", feature = "x11"))]
pub mod render;
pub mod shell;
pub mod state;
Expand All @@ -23,6 +23,8 @@ pub mod udev;
pub mod window_map;
#[cfg(feature = "winit")]
pub mod winit;
#[cfg(feature = "x11")]
pub mod x11;
#[cfg(feature = "xwayland")]
pub mod xwayland;

Expand Down
7 changes: 7 additions & 0 deletions anvil/src/main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,8 @@ static POSSIBLE_BACKENDS: &[&str] = &[
"--winit : Run anvil as a X11 or Wayland client using winit.",
#[cfg(feature = "udev")]
"--tty-udev : Run anvil as a tty udev client (requires root if without logind).",
#[cfg(feature = "x11")]
"--x11 : Run anvil as an X11 client.",
];

fn main() {
Expand Down Expand Up @@ -33,6 +35,11 @@ fn main() {
slog::info!(log, "Starting anvil on a tty using udev");
anvil::udev::run_udev(log);
}
#[cfg(feature = "x11")]
Some("--x11") => {
slog::info!(log, "Starting anvil with x11 backend");
anvil::x11::run_x11(log);
}
Some(other) => {
crit!(log, "Unknown backend: {}", other);
}
Expand Down
2 changes: 2 additions & 0 deletions anvil/src/output_map.rs
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@ use smithay::{

use crate::shell::SurfaceData;

#[derive(Debug)]
pub struct Output {
name: String,
output: output::Output,
Expand Down Expand Up @@ -124,6 +125,7 @@ impl Drop for Output {
}
}

#[derive(Debug)]
pub struct OutputMap {
display: Rc<RefCell<Display>>,
outputs: Vec<Output>,
Expand Down
1 change: 1 addition & 0 deletions anvil/src/state.rs
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,7 @@ use smithay::xwayland::{XWayland, XWaylandEvent};

use crate::{output_map::OutputMap, shell::init_shell, window_map::WindowMap};

#[derive(Debug)]
pub struct AnvilState<BackendData> {
pub backend_data: BackendData,
pub socket_name: Option<String>,
Expand Down
8 changes: 5 additions & 3 deletions anvil/src/window_map.rs
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@ use crate::xwayland::X11Surface;
mod layer_map;
pub use layer_map::{LayerMap, LayerSurface};

#[derive(Clone, PartialEq)]
#[derive(Debug, Clone, PartialEq)]
pub enum Kind {
Xdg(ToplevelSurface),
Wl(ShellSurface),
Expand Down Expand Up @@ -68,7 +68,7 @@ impl Kind {
}
}

#[derive(Clone)]
#[derive(Debug, Clone)]
pub enum PopupKind {
Xdg(PopupSurface),
}
Expand Down Expand Up @@ -125,6 +125,7 @@ impl PopupKind {
}
}

#[derive(Debug)]
struct Window {
location: Point<i32, Logical>,
/// A bounding box over this window and its children.
Expand Down Expand Up @@ -241,11 +242,12 @@ impl Window {
}
}

#[derive(Debug)]
pub struct Popup {
popup: PopupKind,
}

#[derive(Default)]
#[derive(Debug, Default)]
pub struct WindowMap {
windows: Vec<Window>,
popups: Vec<Popup>,
Expand Down
3 changes: 2 additions & 1 deletion anvil/src/window_map/layer_map.rs
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ use smithay::{

use crate::{output_map::Output, shell::SurfaceData};

#[derive(Debug)]
pub struct LayerSurface {
pub surface: wlr_layer::LayerSurface,
pub location: Point<i32, Logical>,
Expand Down Expand Up @@ -122,7 +123,7 @@ impl LayerSurface {
}
}

#[derive(Default)]
#[derive(Debug, Default)]
pub struct LayerMap {
surfaces: Vec<LayerSurface>,
}
Expand Down
Loading