From 6ebf731aea73692f16fe9f91b91487a91503a626 Mon Sep 17 00:00:00 2001 From: Julian Orth Date: Tue, 29 Mar 2022 14:11:25 +0200 Subject: [PATCH] autocommit 2022-03-29 14:11:25 CEST --- Cargo.lock | 112 +++++++++++++ Cargo.toml | 6 +- src/acceptor.rs | 2 +- src/async_engine.rs | 2 +- src/backends/metal.rs | 11 +- src/backends/metal/input.rs | 4 +- src/backends/metal/monitor.rs | 8 +- src/backends/metal/video.rs | 7 +- src/backends/x.rs | 7 +- src/cli.rs | 40 +++++ src/client.rs | 2 +- src/client/error.rs | 2 +- src/client/tasks.rs | 3 +- src/compositor.rs | 135 ++++++++++++++++ src/config.rs | 3 +- src/config/handler.rs | 6 +- src/cursor.rs | 5 +- src/dbus.rs | 6 +- src/dbus/auth.rs | 2 +- src/dbus/holder.rs | 6 +- src/dbus/incoming.rs | 2 +- src/dbus/outgoing.rs | 2 +- src/dbus/socket.rs | 3 +- src/drm/drm.rs | 2 +- src/forker.rs | 10 +- src/forker/io.rs | 2 +- src/globals.rs | 12 +- src/ifs/ipc.rs | 2 +- src/ifs/wl_buffer.rs | 5 +- src/ifs/wl_drm.rs | 2 +- src/ifs/wl_output.rs | 2 +- src/ifs/wl_seat.rs | 4 +- src/ifs/wl_seat/kb_owner.rs | 2 +- src/ifs/wl_shm_pool.rs | 3 +- src/ifs/wl_surface.rs | 12 +- src/ifs/wl_surface/wl_subsurface.rs | 2 +- src/ifs/wl_surface/xdg_surface.rs | 4 +- .../wl_surface/xdg_surface/xdg_toplevel.rs | 8 +- src/ifs/wl_surface/xwindow.rs | 47 +++++- src/ifs/wl_surface/zwlr_layer_surface_v1.rs | 2 +- src/ifs/zwp_linux_buffer_params_v1.rs | 3 +- src/keymap.xkb | 7 + src/libinput.rs | 2 +- src/logind.rs | 10 +- src/main.rs | 152 ++---------------- src/render/renderer/framebuffer.rs | 2 +- src/render/renderer/image.rs | 3 +- src/render/renderer/renderer.rs | 2 +- src/sighand.rs | 3 +- src/state.rs | 5 +- src/tasks.rs | 2 +- src/tasks/backend.rs | 2 +- src/tasks/input_device.rs | 3 +- src/tasks/output.rs | 2 +- src/tasks/slow_clients.rs | 2 +- src/tasks/start_backend.rs | 4 +- src/text.rs | 3 +- src/tree.rs | 2 +- src/tree/container.rs | 5 +- src/tree/float.rs | 5 +- src/tree/output.rs | 4 +- src/tree/toplevel.rs | 6 +- src/tree/walker.rs | 3 +- src/utils/asyncevent.rs | 2 +- src/utils/bufio.rs | 4 +- src/utils/linkedlist.rs | 2 +- src/utils/run_toplevel.rs | 4 +- src/xcon.rs | 17 +- src/xcon/consts.rs | 54 +++---- src/xcon/incoming.rs | 2 +- src/xcon/outgoing.rs | 2 +- src/xwayland.rs | 7 +- src/xwayland/xsocket.rs | 2 +- src/xwayland/xwm.rs | 142 ++++++++++++---- 74 files changed, 650 insertions(+), 317 deletions(-) create mode 100644 src/cli.rs create mode 100644 src/compositor.rs diff --git a/Cargo.lock b/Cargo.lock index 24243e64..79c97c36 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -145,6 +145,37 @@ dependencies = [ "winapi", ] +[[package]] +name = "clap" +version = "3.1.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d8c93436c21e4698bacadf42917db28b23017027a4deccb35dbe47a7e7840123" +dependencies = [ + "atty", + "bitflags", + "clap_derive", + "indexmap", + "lazy_static", + "os_str_bytes", + "strsim", + "termcolor", + "terminal_size", + "textwrap", +] + +[[package]] +name = "clap_derive" +version = "3.1.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "da95d038ede1a964ce99f49cbe27a7fb538d1da595e4b4f70b8c8f338d17bf16" +dependencies = [ + "heck", + "proc-macro-error", + "proc-macro2", + "quote", + "syn", +] + [[package]] name = "default-config" version = "0.1.0" @@ -221,6 +252,18 @@ version = "0.26.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "78cc372d058dcf6d5ecd98510e7fbc9e5aec4d21de70f65fea8fecebcd881bd4" +[[package]] +name = "hashbrown" +version = "0.11.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ab5ef0d4909ef3724cc8cce6ccc8572c5c817592e9285f5464f8e86f8bd3726e" + +[[package]] +name = "heck" +version = "0.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2540771e65fc8cb83cd6e8a237f70c319bd5c29f78ed1084ba5d50eeac86f7f9" + [[package]] name = "hermit-abi" version = "0.1.19" @@ -236,6 +279,16 @@ version = "2.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "9a3a5bfb195931eeb336b2a7b4d761daec841b97f947d34394601737a7bba5e4" +[[package]] +name = "indexmap" +version = "1.8.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "282a6247722caba404c065016bbfa522806e51714c34f5dfc3e4a3a46fcb4223" +dependencies = [ + "autocfg", + "hashbrown", +] + [[package]] name = "isnt" version = "0.1.0" @@ -254,6 +307,7 @@ dependencies = [ "bstr", "byteorder", "chrono", + "clap", "default-config", "env_logger", "futures-util", @@ -372,6 +426,15 @@ version = "1.10.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "87f3e037eac156d1775da914196f0f37741a274155e34a0b7e427c35d2a2ecb9" +[[package]] +name = "os_str_bytes" +version = "6.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8e22443d1643a904602595ba1cd8f7d896afe56d26712531c5ff73a15b2fbf64" +dependencies = [ + "memchr", +] + [[package]] name = "pin-project" version = "1.0.10" @@ -410,6 +473,30 @@ version = "0.2.16" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "eb9f9e6e233e5c4a35559a617bf40a4ec447db2e84c20b55a6f83167b7e57872" +[[package]] +name = "proc-macro-error" +version = "1.0.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "da25490ff9892aab3fcf7c36f08cfb902dd3e71ca0f9f9517bea02a73a5ce38c" +dependencies = [ + "proc-macro-error-attr", + "proc-macro2", + "quote", + "syn", + "version_check", +] + +[[package]] +name = "proc-macro-error-attr" +version = "1.0.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a1be40180e52ecc98ad80b184934baf3d0d29f979574e439af5a55274b35f869" +dependencies = [ + "proc-macro2", + "quote", + "version_check", +] + [[package]] name = "proc-macro2" version = "1.0.36" @@ -508,6 +595,12 @@ version = "1.8.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "f2dd574626839106c320a323308629dcb1acfc96e32a8cba364ddc61ac23ee83" +[[package]] +name = "strsim" +version = "0.10.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "73473c0e59e6d5812c5dfe2a064a6444949f089e20eec9a2e5506596494e4623" + [[package]] name = "syn" version = "1.0.89" @@ -528,6 +621,25 @@ dependencies = [ "winapi-util", ] +[[package]] +name = "terminal_size" +version = "0.1.17" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "633c1a546cee861a1a6d0dc69ebeca693bf4296661ba7852b9d21d159e0506df" +dependencies = [ + "libc", + "winapi", +] + +[[package]] +name = "textwrap" +version = "0.15.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b1141d4d61095b28419e22cb0bbf02755f5e54e0526f97f1e3d1d160e60885fb" +dependencies = [ + "terminal_size", +] + [[package]] name = "thiserror" version = "1.0.30" diff --git a/Cargo.toml b/Cargo.toml index 8773b7d0..deae7ba4 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -29,13 +29,15 @@ isnt = "0.1.0" once_cell = "1.9.0" rand = "0.8.4" smallvec = { version = "1.8.0", features = ["const_generics", "const_new", "union"] } -backtrace = { version = "0.3.64", optional = true } byteorder = "1.4.3" -chrono = { version = "0.4.19", optional = true } bincode = "2.0.0-rc.1" jay-config = { path = "jay-config" } default-config = { path = "default-config" } pin-project = "1.0.10" +clap = { version = "3.1.6", features = ["derive", "wrap_help"] } + +backtrace = { version = "0.3.64", optional = true } +chrono = { version = "0.4.19", optional = true } [build-dependencies] repc = "0.1.1" diff --git a/src/acceptor.rs b/src/acceptor.rs index 89f04a9a..8386320f 100644 --- a/src/acceptor.rs +++ b/src/acceptor.rs @@ -1,7 +1,7 @@ use crate::client::ClientError; use crate::event_loop::{EventLoopDispatcher, EventLoopError, EventLoopId}; use crate::state::State; -use crate::ErrorFmt; +use crate::utils::errorfmt::ErrorFmt; use std::rc::Rc; use thiserror::Error; use uapi::{c, format_ustr, Errno, OwnedFd, Ustring}; diff --git a/src/async_engine.rs b/src/async_engine.rs index efa9f71e..46e416f3 100644 --- a/src/async_engine.rs +++ b/src/async_engine.rs @@ -188,8 +188,8 @@ mod timeout { mod task { use crate::async_engine::queue::DispatchQueue; use crate::async_engine::Phase; + use crate::utils::numcell::NumCell; use crate::utils::ptr_ext::{MutPtrExt, PtrExt}; - use crate::NumCell; use std::cell::{Cell, UnsafeCell}; use std::future::Future; use std::mem::ManuallyDrop; diff --git a/src/backends/metal.rs b/src/backends/metal.rs index 487fe2cc..51429605 100644 --- a/src/backends/metal.rs +++ b/src/backends/metal.rs @@ -2,20 +2,23 @@ mod input; mod monitor; mod video; -use crate::async_engine::AsyncFd; +use crate::async_engine::{AsyncError, AsyncFd}; use crate::backend::{Backend, InputDevice, InputDeviceId, InputEvent}; +use crate::backends::metal::video::{MetalDrmDevice, PendingDrmDevice}; use crate::dbus::DbusError; use crate::drm::drm::DrmError; use crate::drm::gbm::GbmError; use crate::libinput::device::RegisteredDevice; use crate::libinput::{LibInput, LibInputAdapter, LibInputError}; use crate::logind::{LogindError, Session}; -use crate::metal::video::{MetalDrmDevice, PendingDrmDevice}; -use crate::udev::{UdevError, UdevMonitor}; +use crate::render::RenderError; +use crate::state::State; +use crate::udev::{Udev, UdevError, UdevMonitor}; +use crate::utils::clonecell::CloneCell; use crate::utils::copyhashmap::CopyHashMap; +use crate::utils::errorfmt::ErrorFmt; use crate::utils::oserror::OsError; use crate::utils::syncqueue::SyncQueue; -use crate::{AsyncError, CloneCell, ErrorFmt, RenderError, State, Udev}; use std::cell::{Cell, RefCell}; use std::ffi::{CStr, CString}; use std::future::pending; diff --git a/src/backends/metal/input.rs b/src/backends/metal/input.rs index 5f31a36b..1abb7949 100644 --- a/src/backends/metal/input.rs +++ b/src/backends/metal/input.rs @@ -1,12 +1,12 @@ use crate::async_engine::FdStatus; use crate::backend::{InputEvent, KeyState, ScrollAxis}; +use crate::backends::metal::MetalBackend; use crate::libinput::consts::{ LIBINPUT_BUTTON_STATE_PRESSED, LIBINPUT_KEY_STATE_PRESSED, LIBINPUT_POINTER_AXIS_SCROLL_HORIZONTAL, LIBINPUT_POINTER_AXIS_SCROLL_VERTICAL, }; use crate::libinput::event::LibInputEvent; -use crate::metal::MetalBackend; -use crate::ErrorFmt; +use crate::utils::errorfmt::ErrorFmt; use std::rc::Rc; macro_rules! unpack { diff --git a/src/backends/metal/monitor.rs b/src/backends/metal/monitor.rs index 31392e77..3e412cb9 100644 --- a/src/backends/metal/monitor.rs +++ b/src/backends/metal/monitor.rs @@ -1,13 +1,13 @@ use crate::async_engine::FdStatus; use crate::backend::BackendEvent; +use crate::backends::metal::video::{MetalDrmDevice, PendingDrmDevice}; +use crate::backends::metal::{MetalBackend, MetalDevice, MetalError, MetalInputDevice}; use crate::dbus::TRUE; use crate::drm::drm::DrmMaster; -use crate::metal::video::PendingDrmDevice; -use crate::metal::{MetalBackend, MetalDevice, MetalDrmDevice, MetalError, MetalInputDevice}; -use crate::org::freedesktop::login1::session::{PauseDevice, ResumeDevice}; use crate::udev::UdevDevice; +use crate::utils::errorfmt::ErrorFmt; use crate::utils::nonblock::set_nonblock; -use crate::ErrorFmt; +use crate::wire_dbus::org::freedesktop::login1::session::{PauseDevice, ResumeDevice}; use bstr::ByteSlice; use std::cell::Cell; use std::rc::Rc; diff --git a/src/backends/metal/video.rs b/src/backends/metal/video.rs index 9d09322d..7ad7591b 100644 --- a/src/backends/metal/video.rs +++ b/src/backends/metal/video.rs @@ -1,5 +1,6 @@ use crate::async_engine::{AsyncFd, SpawnedFuture}; use crate::backend::{BackendEvent, Output, OutputId}; +use crate::backends::metal::{DrmId, MetalBackend, MetalError}; use crate::drm::drm::{ drm_mode_modeinfo, Change, ConnectorStatus, ConnectorType, DrmBlob, DrmConnector, DrmCrtc, DrmEncoder, DrmError, DrmEvent, DrmFramebuffer, DrmMaster, DrmModeInfo, DrmObject, DrmPlane, @@ -9,11 +10,13 @@ use crate::drm::drm::{ use crate::drm::gbm::{GbmDevice, GBM_BO_USE_RENDERING, GBM_BO_USE_SCANOUT}; use crate::drm::{ModifiedFormat, INVALID_MODIFIER}; use crate::format::{Format, XRGB8888}; -use crate::metal::{DrmId, MetalBackend, MetalError}; use crate::render::{Framebuffer, RenderContext}; +use crate::state::State; use crate::utils::bitflags::BitflagsExt; +use crate::utils::clonecell::CloneCell; +use crate::utils::errorfmt::ErrorFmt; +use crate::utils::numcell::NumCell; use crate::utils::oserror::OsError; -use crate::{CloneCell, ErrorFmt, NumCell, State}; use ahash::{AHashMap, AHashSet}; use bstr::{BString, ByteSlice}; use std::cell::Cell; diff --git a/src/backends/x.rs b/src/backends/x.rs index 669a0862..89ddb173 100644 --- a/src/backends/x.rs +++ b/src/backends/x.rs @@ -1,4 +1,4 @@ -use crate::async_engine::SpawnedFuture; +use crate::async_engine::{Phase, SpawnedFuture}; use crate::backend::{ Backend, BackendEvent, InputDevice, InputDeviceId, InputEvent, KeyState, Output, OutputId, ScrollAxis, @@ -9,8 +9,12 @@ use crate::drm::{ModifiedFormat, INVALID_MODIFIER}; use crate::fixed::Fixed; use crate::format::XRGB8888; use crate::render::{Framebuffer, RenderContext, RenderError}; +use crate::state::State; use crate::utils::clonecell::CloneCell; use crate::utils::copyhashmap::CopyHashMap; +use crate::utils::errorfmt::ErrorFmt; +use crate::utils::numcell::NumCell; +use crate::utils::queue::AsyncQueue; use crate::wire_xcon::{ ChangeProperty, ChangeWindowAttributes, ConfigureNotify, CreateCursor, CreatePixmap, CreateWindow, CreateWindowValues, DestroyNotify, Dri3Open, Dri3PixmapFromBuffer, @@ -33,7 +37,6 @@ use crate::xcon::consts::{ XKB_PER_CLIENT_FLAG_DETECTABLE_AUTO_REPEAT, }; use crate::xcon::{Event, XEvent, Xcon, XconError}; -use crate::{AsyncQueue, ErrorFmt, NumCell, Phase, State}; use std::borrow::Cow; use std::cell::{Cell, RefCell}; use std::collections::VecDeque; diff --git a/src/cli.rs b/src/cli.rs new file mode 100644 index 00000000..359fafe7 --- /dev/null +++ b/src/cli.rs @@ -0,0 +1,40 @@ +use clap::{ArgEnum, Args, Parser, Subcommand}; + +#[derive(Parser, Debug)] +pub struct Cli { + #[clap(flatten)] + pub global: GlobalArgs, + #[clap(subcommand)] + pub command: Cmd, +} + +#[derive(Args, Debug)] +pub struct GlobalArgs { + #[clap(long)] + hurr: String, +} + +#[derive(Subcommand, Debug)] +pub enum Cmd { + /// Run the compositor + Run, + Test(Test), +} + +#[derive(Args, Debug)] +pub struct Test { + /// a + /// + /// b + /// + /// c + #[clap(long, use_value_delimiter = true, arg_enum)] + shell: Vec, +} + +#[derive(ArgEnum, Debug, Copy, Clone)] +pub enum Hurr { + Bash, + Fish, + Zsh, +} diff --git a/src/client.rs b/src/client.rs index 4c0e7e7b..ae7fdc45 100644 --- a/src/client.rs +++ b/src/client.rs @@ -9,11 +9,11 @@ use crate::object::{Interface, Object, ObjectId, WL_DISPLAY_ID}; use crate::state::State; use crate::utils::asyncevent::AsyncEvent; use crate::utils::buffd::{MsgFormatter, MsgParser, MsgParserError, OutBufferSwapchain}; +use crate::utils::errorfmt::ErrorFmt; use crate::utils::numcell::NumCell; use crate::utils::queue::AsyncQueue; use crate::wire::WlRegistryId; use crate::xwayland::XWaylandEvent; -use crate::ErrorFmt; use ahash::AHashMap; pub use error::{ClientError, ObjectError}; use std::cell::{Cell, RefCell, RefMut}; diff --git a/src/client/error.rs b/src/client/error.rs index cdc0f399..e456473c 100644 --- a/src/client/error.rs +++ b/src/client/error.rs @@ -1,8 +1,8 @@ +use crate::async_engine::AsyncError; use crate::client::ClientId; use crate::object::{Interface, ObjectId}; use crate::utils::buffd::{BufFdError, MsgParserError}; use crate::wire::WlDisplayId; -use crate::AsyncError; use std::error::Error; use thiserror::Error; diff --git a/src/client/tasks.rs b/src/client/tasks.rs index 7224411f..f1ed416b 100644 --- a/src/client/tasks.rs +++ b/src/client/tasks.rs @@ -1,8 +1,9 @@ +use crate::async_engine::Phase; use crate::client::{Client, ClientError}; use crate::object::ObjectId; use crate::utils::buffd::{BufFdIn, BufFdOut, MsgParser}; +use crate::utils::errorfmt::ErrorFmt; use crate::utils::vec_ext::VecExt; -use crate::{ErrorFmt, Phase}; use futures_util::{select, FutureExt}; use std::collections::VecDeque; use std::mem; diff --git a/src/compositor.rs b/src/compositor.rs new file mode 100644 index 00000000..1b2970b3 --- /dev/null +++ b/src/compositor.rs @@ -0,0 +1,135 @@ +use crate::acceptor::{Acceptor, AcceptorError}; +use crate::async_engine::{AsyncEngine, AsyncError, Phase}; +use crate::client::Clients; +use crate::clientmem::ClientMemError; +use crate::config::ConfigProxy; +use crate::dbus::Dbus; +use crate::event_loop::{EventLoop, EventLoopError}; +use crate::forker::ForkerError; +use crate::globals::Globals; +use crate::ifs::wl_surface::NoneSurfaceExt; +use crate::render::RenderError; +use crate::sighand::SighandError; +use crate::state::State; +use crate::tree::{ + container_layout, container_render_data, float_layout, float_titles, DisplayNode, NodeIds, +}; +use crate::utils::errorfmt::ErrorFmt; +use crate::utils::fdcloser::FdCloser; +use crate::utils::numcell::NumCell; +use crate::utils::queue::AsyncQueue; +use crate::utils::run_toplevel::RunToplevel; +use crate::wheel::{Wheel, WheelError}; +use crate::xkbcommon::XkbContext; +use crate::{clientmem, forker, leaks, render, sighand, tasks, xwayland}; +use log::LevelFilter; +use std::cell::Cell; +use std::ops::Deref; +use std::rc::Rc; +use thiserror::Error; + +pub fn start_compositor() { + env_logger::builder() + .format_timestamp_millis() + .filter_level(LevelFilter::Info) + .filter_level(LevelFilter::Debug) + // .filter_level(LevelFilter::Trace) + .init(); + if let Err(e) = main_() { + log::error!("A fatal error occurred: {}", ErrorFmt(e)); + std::process::exit(1); + } +} + +#[derive(Debug, Error)] +enum MainError { + #[error("The client acceptor caused an error")] + AcceptorError(#[from] AcceptorError), + #[error("The event loop caused an error")] + EventLoopError(#[from] EventLoopError), + #[error("The signal handler caused an error")] + SighandError(#[from] SighandError), + #[error("The clientmem subsystem caused an error")] + ClientmemError(#[from] ClientMemError), + #[error("The timer subsystem caused an error")] + WheelError(#[from] WheelError), + #[error("The async subsystem caused an error")] + AsyncError(#[from] AsyncError), + #[error("The render backend caused an error")] + RenderError(#[from] RenderError), + #[error("The ol' forker caused an error")] + ForkerError(#[from] ForkerError), +} + +fn main_() -> Result<(), MainError> { + let forker = Rc::new(forker::ForkerProxy::create()?); + leaks::init(); + render::init()?; + clientmem::init()?; + let el = EventLoop::new()?; + sighand::install(&el)?; + let xkb_ctx = XkbContext::new().unwrap(); + let xkb_keymap = xkb_ctx.keymap_from_str(include_str!("keymap.xkb")).unwrap(); + let wheel = Wheel::install(&el)?; + let engine = AsyncEngine::install(&el, &wheel)?; + let (_run_toplevel_future, run_toplevel) = RunToplevel::install(&engine); + let node_ids = NodeIds::default(); + let state = Rc::new(State { + xkb_ctx, + backend: Default::default(), + forker: Default::default(), + default_keymap: xkb_keymap, + eng: engine.clone(), + el: el.clone(), + render_ctx: Default::default(), + cursors: Default::default(), + wheel, + clients: Clients::new(), + next_name: NumCell::new(1), + globals: Globals::new(), + output_ids: Default::default(), + root: Rc::new(DisplayNode::new(node_ids.next())), + node_ids, + backend_events: AsyncQueue::new(), + output_handlers: Default::default(), + seat_ids: Default::default(), + outputs: Default::default(), + seat_queue: Default::default(), + slow_clients: AsyncQueue::new(), + none_surface_ext: Rc::new(NoneSurfaceExt), + tree_changed_sent: Cell::new(false), + config: Default::default(), + input_device_ids: Default::default(), + input_device_handlers: Default::default(), + theme: Default::default(), + pending_container_layout: Default::default(), + pending_container_render_data: Default::default(), + pending_float_layout: Default::default(), + pending_float_titles: Default::default(), + dbus: Dbus::new(&engine, &run_toplevel), + fdcloser: FdCloser::new(), + }); + forker.install(&state); + let config = ConfigProxy::default(&state); + state.config.set(Some(Rc::new(config))); + let _global_event_handler = engine.spawn(tasks::handle_backend_events(state.clone())); + let _slow_client_handler = engine.spawn(tasks::handle_slow_clients(state.clone())); + let _container_do_layout = engine.spawn2(Phase::Layout, container_layout(state.clone())); + let _container_render_titles = + engine.spawn2(Phase::PostLayout, container_render_data(state.clone())); + let _float_do_layout = engine.spawn2(Phase::Layout, float_layout(state.clone())); + let _float_render_titles = engine.spawn2(Phase::PostLayout, float_titles(state.clone())); + let socket_path = Acceptor::install(&state)?; + forker.setenv(b"WAYLAND_DISPLAY", socket_path.as_bytes()); + forker.setenv(b"_JAVA_AWT_WM_NONREPARENTING", b"1"); + let _xwayland = engine.spawn(xwayland::manage(state.clone())); + let _backend = engine.spawn(tasks::start_backend(state.clone())); + el.run()?; + drop(_xwayland); + state.clients.clear(); + for (_, seat) in state.globals.seats.lock().deref() { + seat.clear(); + } + leaks::log_leaked(); + Ok(()) +} diff --git a/src/config.rs b/src/config.rs index 59d5cca8..27a79778 100644 --- a/src/config.rs +++ b/src/config.rs @@ -3,8 +3,9 @@ mod handler; use crate::backend::InputDeviceId; use crate::config::handler::ConfigProxyHandler; use crate::ifs::wl_seat::SeatId; +use crate::state::State; +use crate::utils::numcell::NumCell; use crate::utils::ptr_ext::PtrExt; -use crate::{NumCell, State}; use jay_config::_private::ipc::{InitMessage, ServerMessage, V1InitMessage}; use jay_config::_private::{bincode_ops, ConfigEntry, VERSION}; use jay_config::keyboard::ModifiedKeySym; diff --git a/src/config/handler.rs b/src/config/handler.rs index 55e4d77d..43650879 100644 --- a/src/config/handler.rs +++ b/src/config/handler.rs @@ -1,13 +1,15 @@ +use crate::backend; use crate::backend::InputDeviceId; use crate::ifs::wl_seat::{SeatId, WlSeatGlobal}; -use crate::state::DeviceHandlerData; +use crate::state::{DeviceHandlerData, State}; use crate::tree::walker::NodeVisitorBase; use crate::tree::{ContainerNode, ContainerSplit, FloatNode, Node}; use crate::utils::copyhashmap::CopyHashMap; use crate::utils::debug_fn::debug_fn; +use crate::utils::errorfmt::ErrorFmt; +use crate::utils::numcell::NumCell; use crate::utils::stack::Stack; use crate::xkbcommon::XkbKeymap; -use crate::{backend, ErrorFmt, NumCell, State}; use bincode::error::DecodeError; use jay_config::_private::bincode_ops; use jay_config::_private::ipc::{ClientMessage, Response, ServerMessage}; diff --git a/src/cursor.rs b/src/cursor.rs index bcb3b024..e32fa76b 100644 --- a/src/cursor.rs +++ b/src/cursor.rs @@ -1,7 +1,8 @@ use crate::format::ARGB8888; use crate::rect::Rect; -use crate::render::{RenderContext, Renderer, Texture}; -use crate::{ErrorFmt, NumCell, RenderError}; +use crate::render::{RenderContext, RenderError, Renderer, Texture}; +use crate::utils::errorfmt::ErrorFmt; +use crate::utils::numcell::NumCell; use ahash::AHashSet; use bstr::{BStr, BString, ByteSlice, ByteVec}; use byteorder::{LittleEndian, ReadBytesExt}; diff --git a/src/dbus.rs b/src/dbus.rs index e559d82e..1936fcc9 100644 --- a/src/dbus.rs +++ b/src/dbus.rs @@ -1,10 +1,12 @@ -use crate::async_engine::{AsyncFd, SpawnedFuture}; +use crate::async_engine::{AsyncEngine, AsyncError, AsyncFd, SpawnedFuture}; use crate::dbus::property::GetReply; use crate::dbus::types::{ObjectPath, Signature, Variant}; use crate::utils::bufio::{BufIo, BufIoError}; +use crate::utils::clonecell::CloneCell; use crate::utils::copyhashmap::CopyHashMap; +use crate::utils::numcell::NumCell; +use crate::utils::run_toplevel::RunToplevel; use crate::utils::vecstorage::VecStorage; -use crate::{AsyncEngine, AsyncError, CloneCell, NumCell, RunToplevel}; use ahash::AHashMap; use std::borrow::Cow; use std::cell::{Cell, RefCell}; diff --git a/src/dbus/auth.rs b/src/dbus/auth.rs index dd0fb4a5..d1a6ed16 100644 --- a/src/dbus/auth.rs +++ b/src/dbus/auth.rs @@ -1,8 +1,8 @@ use crate::dbus::incoming::handle_incoming; use crate::dbus::outgoing::handle_outgoing; use crate::dbus::{DbusError, DbusSocket}; +use crate::utils::errorfmt::ErrorFmt; use crate::utils::hex; -use crate::ErrorFmt; use std::io::Write; use std::rc::Rc; use uapi::{c, Errno}; diff --git a/src/dbus/holder.rs b/src/dbus/holder.rs index 70004324..68f320de 100644 --- a/src/dbus/holder.rs +++ b/src/dbus/holder.rs @@ -1,7 +1,11 @@ +use crate::async_engine::AsyncEngine; use crate::dbus::auth::handle_auth; use crate::dbus::{DbusError, DbusHolder, DbusSocket}; use crate::utils::bufio::BufIo; -use crate::{org, AsyncEngine, ErrorFmt, NumCell, RunToplevel}; +use crate::utils::errorfmt::ErrorFmt; +use crate::utils::numcell::NumCell; +use crate::utils::run_toplevel::RunToplevel; +use crate::wire_dbus::org; use std::cell::Cell; use std::rc::Rc; use uapi::c; diff --git a/src/dbus/incoming.rs b/src/dbus/incoming.rs index 6333248d..490f221b 100644 --- a/src/dbus/incoming.rs +++ b/src/dbus/incoming.rs @@ -6,8 +6,8 @@ use crate::dbus::{ CallError, DbusError, DbusSocket, Headers, Parser, MSG_ERROR, MSG_METHOD_RETURN, MSG_SIGNAL, }; use crate::utils::bufio::BufIoIncoming; +use crate::utils::errorfmt::ErrorFmt; use crate::utils::ptr_ext::{MutPtrExt, PtrExt}; -use crate::ErrorFmt; use std::cell::UnsafeCell; use std::ops::Deref; use std::rc::Rc; diff --git a/src/dbus/outgoing.rs b/src/dbus/outgoing.rs index b4910c96..c79e911f 100644 --- a/src/dbus/outgoing.rs +++ b/src/dbus/outgoing.rs @@ -1,5 +1,5 @@ use crate::dbus::DbusSocket; -use crate::ErrorFmt; +use crate::utils::errorfmt::ErrorFmt; use std::rc::Rc; pub async fn handle_outgoing(socket: Rc) { diff --git a/src/dbus/socket.rs b/src/dbus/socket.rs index 3d594ca4..9189858a 100644 --- a/src/dbus/socket.rs +++ b/src/dbus/socket.rs @@ -8,7 +8,8 @@ use crate::dbus::{ NO_REPLY_EXPECTED, }; use crate::utils::bufio::BufIoMessage; -use crate::{org, ErrorFmt}; +use crate::utils::errorfmt::ErrorFmt; +use crate::wire_dbus::org; use std::cell::Cell; use std::collections::hash_map::Entry; use std::fmt::Write; diff --git a/src/drm/drm.rs b/src/drm/drm.rs index f99a935a..110f6f16 100644 --- a/src/drm/drm.rs +++ b/src/drm/drm.rs @@ -25,9 +25,9 @@ use uapi::{c, Errno, OwnedFd, Pod, Ustring}; use crate::drm::dma::DmaBuf; use crate::drm::INVALID_MODIFIER; +use crate::utils::errorfmt::ErrorFmt; use crate::utils::stack::Stack; use crate::utils::syncqueue::SyncQueue; -use crate::ErrorFmt; pub use sys::{ drm_mode_modeinfo, DRM_CLIENT_CAP_ATOMIC, DRM_MODE_ATOMIC_ALLOW_MODESET, DRM_MODE_ATOMIC_NONBLOCK, DRM_MODE_PAGE_FLIP_EVENT, diff --git a/src/forker.rs b/src/forker.rs index 311be675..f6d57a31 100644 --- a/src/forker.rs +++ b/src/forker.rs @@ -1,12 +1,18 @@ mod clone3; mod io; -use crate::async_engine::{AsyncFd, SpawnedFuture}; +use crate::async_engine::{AsyncEngine, AsyncFd, SpawnedFuture}; +use crate::event_loop::EventLoop; use crate::forker::clone3::{fork_with_pidfd, Forked}; use crate::forker::io::{IoIn, IoOut}; +use crate::state::State; use crate::utils::buffd::BufFdError; use crate::utils::copyhashmap::CopyHashMap; -use crate::{xwayland, AsyncEngine, AsyncQueue, ErrorFmt, EventLoop, NumCell, State, Wheel}; +use crate::utils::errorfmt::ErrorFmt; +use crate::utils::numcell::NumCell; +use crate::utils::queue::AsyncQueue; +use crate::wheel::Wheel; +use crate::xwayland; use bincode::error::{DecodeError, EncodeError}; use bincode::{Decode, Encode}; use jay_config::_private::bincode_ops; diff --git a/src/forker/io.rs b/src/forker/io.rs index 3a38fe98..a8a9fd31 100644 --- a/src/forker/io.rs +++ b/src/forker/io.rs @@ -3,9 +3,9 @@ use std::mem; use std::rc::Rc; use crate::async_engine::AsyncFd; +use crate::forker::ForkerError; use crate::utils::buffd::{BufFdIn, BufFdOut}; use crate::utils::vec_ext::VecExt; -use crate::ForkerError; use jay_config::_private::bincode_ops; use uapi::OwnedFd; diff --git a/src/globals.rs b/src/globals.rs index 5621bab6..635b850a 100644 --- a/src/globals.rs +++ b/src/globals.rs @@ -2,18 +2,22 @@ use crate::client::Client; use crate::ifs::ipc::wl_data_device_manager::WlDataDeviceManagerGlobal; use crate::ifs::ipc::zwp_primary_selection_device_manager_v1::ZwpPrimarySelectionDeviceManagerV1Global; use crate::ifs::org_kde_kwin_server_decoration_manager::OrgKdeKwinServerDecorationManagerGlobal; +use crate::ifs::wl_compositor::WlCompositorGlobal; use crate::ifs::wl_drm::WlDrmGlobal; use crate::ifs::wl_output::WlOutputGlobal; use crate::ifs::wl_registry::WlRegistry; use crate::ifs::wl_seat::WlSeatGlobal; +use crate::ifs::wl_shm::WlShmGlobal; +use crate::ifs::wl_subcompositor::WlSubcompositorGlobal; +use crate::ifs::xdg_wm_base::XdgWmBaseGlobal; use crate::ifs::zwlr_layer_shell_v1::ZwlrLayerShellV1Global; +use crate::ifs::zwp_linux_dmabuf_v1::ZwpLinuxDmabufV1Global; +use crate::ifs::zxdg_decoration_manager_v1::ZxdgDecorationManagerV1Global; use crate::ifs::zxdg_output_manager_v1::ZxdgOutputManagerV1Global; use crate::object::{Interface, ObjectId}; +use crate::state::State; use crate::utils::copyhashmap::CopyHashMap; -use crate::{ - NumCell, State, WlCompositorGlobal, WlShmGlobal, WlSubcompositorGlobal, XdgWmBaseGlobal, - ZwpLinuxDmabufV1Global, ZxdgDecorationManagerV1Global, -}; +use crate::utils::numcell::NumCell; use ahash::AHashMap; use std::cell::RefMut; use std::error::Error; diff --git a/src/ifs/ipc.rs b/src/ifs/ipc.rs index eaed02d2..85d58552 100644 --- a/src/ifs/ipc.rs +++ b/src/ifs/ipc.rs @@ -3,8 +3,8 @@ use crate::ifs::wl_seat::WlSeatGlobal; use crate::object::ObjectId; use crate::utils::bitflags::BitflagsExt; use crate::utils::clonecell::CloneCell; +use crate::utils::numcell::NumCell; use crate::utils::smallmap::SmallMap; -use crate::NumCell; use ahash::AHashSet; use std::cell::{Cell, RefCell}; use std::ops::Deref; diff --git a/src/ifs/wl_buffer.rs b/src/ifs/wl_buffer.rs index 072a3f3e..463da48d 100644 --- a/src/ifs/wl_buffer.rs +++ b/src/ifs/wl_buffer.rs @@ -1,16 +1,15 @@ use crate::client::{Client, ClientError}; -use crate::clientmem::{ClientMem, ClientMemOffset}; +use crate::clientmem::{ClientMem, ClientMemError, ClientMemOffset}; use crate::format::Format; use crate::leaks::Tracker; use crate::object::Object; use crate::rect::Rect; -use crate::render::{Image, Texture}; +use crate::render::{Image, RenderError, Texture}; use crate::utils::buffd::MsgParser; use crate::utils::buffd::MsgParserError; use crate::utils::clonecell::CloneCell; use crate::wire::wl_buffer::*; use crate::wire::WlBufferId; -use crate::{ClientMemError, RenderError}; use std::cell::Cell; use std::rc::Rc; use thiserror::Error; diff --git a/src/ifs/wl_drm.rs b/src/ifs/wl_drm.rs index b3bbc281..ab7d91ed 100644 --- a/src/ifs/wl_drm.rs +++ b/src/ifs/wl_drm.rs @@ -5,11 +5,11 @@ use crate::globals::{Global, GlobalName}; use crate::ifs::wl_buffer::WlBuffer; use crate::leaks::Tracker; use crate::object::Object; +use crate::render::RenderError; use crate::utils::buffd::MsgParser; use crate::utils::buffd::MsgParserError; use crate::wire::wl_drm::*; use crate::wire::WlDrmId; -use crate::RenderError; use bstr::ByteSlice; use std::ffi::CString; use std::rc::Rc; diff --git a/src/ifs/wl_output.rs b/src/ifs/wl_output.rs index 445c342d..d5e44b29 100644 --- a/src/ifs/wl_output.rs +++ b/src/ifs/wl_output.rs @@ -8,10 +8,10 @@ use crate::rect::Rect; use crate::tree::OutputNode; use crate::utils::buffd::MsgParser; use crate::utils::buffd::MsgParserError; +use crate::utils::clonecell::CloneCell; use crate::utils::copyhashmap::CopyHashMap; use crate::wire::wl_output::*; use crate::wire::{WlOutputId, ZxdgOutputV1Id}; -use crate::CloneCell; use ahash::AHashMap; use std::cell::{Cell, RefCell}; use std::collections::hash_map::Entry; diff --git a/src/ifs/wl_seat.rs b/src/ifs/wl_seat.rs index b3253d8f..c3d2e32f 100644 --- a/src/ifs/wl_seat.rs +++ b/src/ifs/wl_seat.rs @@ -25,6 +25,7 @@ use crate::ifs::wl_seat::wl_touch::WlTouch; use crate::ifs::wl_surface::WlSurface; use crate::leaks::Tracker; use crate::object::{Object, ObjectId}; +use crate::state::State; use crate::tree::toplevel::ToplevelNode; use crate::tree::{ContainerSplit, FloatNode, FoundNode, Node}; use crate::utils::asyncevent::AsyncEvent; @@ -32,13 +33,14 @@ use crate::utils::buffd::MsgParser; use crate::utils::buffd::MsgParserError; use crate::utils::clonecell::CloneCell; use crate::utils::copyhashmap::CopyHashMap; +use crate::utils::errorfmt::ErrorFmt; use crate::utils::linkedlist::{LinkedList, LinkedNode}; +use crate::utils::numcell::NumCell; use crate::wire::wl_seat::*; use crate::wire::{ WlDataDeviceId, WlKeyboardId, WlPointerId, WlSeatId, ZwpPrimarySelectionDeviceV1Id, }; use crate::xkbcommon::{XkbKeymap, XkbState}; -use crate::{ErrorFmt, NumCell, State}; use ahash::{AHashMap, AHashSet}; pub use event_handling::NodeSeatState; use jay_config::keyboard::mods::Modifiers; diff --git a/src/ifs/wl_seat/kb_owner.rs b/src/ifs/wl_seat/kb_owner.rs index e50432bb..b22739ac 100644 --- a/src/ifs/wl_seat/kb_owner.rs +++ b/src/ifs/wl_seat/kb_owner.rs @@ -1,6 +1,6 @@ use crate::ifs::wl_seat::WlSeatGlobal; use crate::tree::Node; -use crate::CloneCell; +use crate::utils::clonecell::CloneCell; use std::rc::Rc; pub struct KbOwnerHolder { diff --git a/src/ifs/wl_shm_pool.rs b/src/ifs/wl_shm_pool.rs index af50250c..7e24bf8e 100644 --- a/src/ifs/wl_shm_pool.rs +++ b/src/ifs/wl_shm_pool.rs @@ -1,5 +1,5 @@ use crate::client::{Client, ClientError}; -use crate::clientmem::ClientMem; +use crate::clientmem::{ClientMem, ClientMemError}; use crate::format::{formats, map_wayland_format_id}; use crate::ifs::wl_buffer::{WlBuffer, WlBufferError}; use crate::leaks::Tracker; @@ -9,7 +9,6 @@ use crate::utils::buffd::MsgParserError; use crate::utils::clonecell::CloneCell; use crate::wire::wl_shm_pool::*; use crate::wire::WlShmPoolId; -use crate::ClientMemError; use std::rc::Rc; use thiserror::Error; use uapi::OwnedFd; diff --git a/src/ifs/wl_surface.rs b/src/ifs/wl_surface.rs index 467b6af7..f108f31e 100644 --- a/src/ifs/wl_surface.rs +++ b/src/ifs/wl_surface.rs @@ -12,23 +12,24 @@ use crate::ifs::wl_callback::WlCallback; use crate::ifs::wl_seat::{Dnd, NodeSeatState, SeatId, WlSeatGlobal}; use crate::ifs::wl_surface::cursor::CursorSurface; use crate::ifs::wl_surface::wl_subsurface::WlSubsurface; -use crate::ifs::wl_surface::xdg_surface::{XdgSurfaceError}; +use crate::ifs::wl_surface::xdg_surface::XdgSurfaceError; use crate::ifs::wl_surface::zwlr_layer_surface_v1::ZwlrLayerSurfaceV1Error; use crate::leaks::Tracker; use crate::object::Object; use crate::pixman::Region; use crate::rect::Rect; use crate::render::Renderer; +use crate::tree::toplevel::ToplevelNode; use crate::tree::walker::NodeVisitor; use crate::tree::{ContainerNode, ContainerSplit, Node, NodeId}; use crate::utils::buffd::{MsgParser, MsgParserError}; use crate::utils::clonecell::CloneCell; use crate::utils::linkedlist::LinkedList; +use crate::utils::numcell::NumCell; use crate::utils::smallmap::SmallMap; use crate::wire::wl_surface::*; use crate::wire::{WlOutputId, WlSurfaceId}; use crate::xkbcommon::ModifierState; -use crate::NumCell; use ahash::AHashMap; use jay_config::Direction; use std::cell::{Cell, RefCell}; @@ -37,7 +38,6 @@ use std::mem; use std::ops::{Deref, DerefMut}; use std::rc::Rc; use thiserror::Error; -use crate::tree::toplevel::ToplevelNode; #[allow(dead_code)] const INVALID_SCALE: u32 = 0; @@ -644,13 +644,15 @@ impl Node for WlSurface { } fn get_parent_mono(&self) -> Option { - self.toplevel.get() + self.toplevel + .get() .and_then(|t| t.parent()) .and_then(|p| p.get_mono()) } fn get_parent_split(&self) -> Option { - self.toplevel.get() + self.toplevel + .get() .and_then(|t| t.parent()) .and_then(|p| p.get_split()) } diff --git a/src/ifs/wl_surface/wl_subsurface.rs b/src/ifs/wl_surface/wl_subsurface.rs index e1826076..aaaeec9f 100644 --- a/src/ifs/wl_surface/wl_subsurface.rs +++ b/src/ifs/wl_surface/wl_subsurface.rs @@ -9,9 +9,9 @@ use crate::rect::Rect; use crate::utils::buffd::MsgParser; use crate::utils::buffd::MsgParserError; use crate::utils::linkedlist::LinkedNode; +use crate::utils::numcell::NumCell; use crate::wire::wl_subsurface::*; use crate::wire::WlSubsurfaceId; -use crate::NumCell; use std::cell::{Cell, RefCell}; use std::ops::Deref; use std::rc::Rc; diff --git a/src/ifs/wl_surface/xdg_surface.rs b/src/ifs/wl_surface/xdg_surface.rs index 4800688c..fc5cda1e 100644 --- a/src/ifs/wl_surface/xdg_surface.rs +++ b/src/ifs/wl_surface/xdg_surface.rs @@ -2,7 +2,7 @@ pub mod xdg_popup; pub mod xdg_toplevel; use crate::client::ClientError; -use crate::ifs::wl_seat::{NodeSeatState}; +use crate::ifs::wl_seat::NodeSeatState; use crate::ifs::wl_surface::xdg_surface::xdg_popup::{XdgPopup, XdgPopupError}; use crate::ifs::wl_surface::xdg_surface::xdg_toplevel::XdgToplevel; use crate::ifs::wl_surface::{ @@ -17,9 +17,9 @@ use crate::utils::buffd::MsgParser; use crate::utils::buffd::MsgParserError; use crate::utils::clonecell::CloneCell; use crate::utils::copyhashmap::CopyHashMap; +use crate::utils::numcell::NumCell; use crate::wire::xdg_surface::*; use crate::wire::{WlSurfaceId, XdgPopupId, XdgSurfaceId}; -use crate::NumCell; use std::cell::Cell; use std::fmt::Debug; use std::rc::Rc; diff --git a/src/ifs/wl_surface/xdg_surface/xdg_toplevel.rs b/src/ifs/wl_surface/xdg_surface/xdg_toplevel.rs index 08f6ce5d..42054466 100644 --- a/src/ifs/wl_surface/xdg_surface/xdg_toplevel.rs +++ b/src/ifs/wl_surface/xdg_surface/xdg_toplevel.rs @@ -1,22 +1,24 @@ +use crate::bugs; use crate::bugs::Bugs; use crate::client::{Client, ClientError}; use crate::cursor::KnownCursor; use crate::fixed::Fixed; use crate::ifs::wl_seat::{NodeSeatState, WlSeatGlobal}; use crate::ifs::wl_surface::xdg_surface::{XdgSurface, XdgSurfaceError, XdgSurfaceExt}; +use crate::ifs::wl_surface::WlSurface; use crate::leaks::Tracker; use crate::object::Object; use crate::rect::Rect; use crate::render::Renderer; +use crate::tree::toplevel::{ToplevelData, ToplevelNode}; use crate::tree::walker::NodeVisitor; -use crate::tree::{FindTreeResult}; +use crate::tree::FindTreeResult; use crate::tree::{FoundNode, Node, NodeId, ToplevelNodeId, WorkspaceNode}; use crate::utils::buffd::MsgParser; use crate::utils::buffd::MsgParserError; use crate::utils::clonecell::CloneCell; use crate::wire::xdg_toplevel::*; use crate::wire::XdgToplevelId; -use crate::{bugs}; use ahash::{AHashMap, AHashSet}; use jay_config::Direction; use num_derive::FromPrimitive; @@ -25,8 +27,6 @@ use std::fmt::{Debug, Formatter}; use std::mem; use std::ops::Deref; use std::rc::Rc; -use crate::ifs::wl_surface::WlSurface; -use crate::tree::toplevel::{ToplevelData, ToplevelNode}; use thiserror::Error; #[derive(Copy, Clone, Debug, FromPrimitive)] diff --git a/src/ifs/wl_surface/xwindow.rs b/src/ifs/wl_surface/xwindow.rs index 2655a230..2e407639 100644 --- a/src/ifs/wl_surface/xwindow.rs +++ b/src/ifs/wl_surface/xwindow.rs @@ -5,16 +5,18 @@ use crate::ifs::wl_seat::{NodeSeatState, SeatId, WlSeatGlobal}; use crate::ifs::wl_surface::{SurfaceExt, SurfaceRole, WlSurface, WlSurfaceError}; use crate::rect::Rect; use crate::render::Renderer; +use crate::state::State; use crate::tree::toplevel::{ToplevelData, ToplevelNode}; use crate::tree::walker::NodeVisitor; use crate::tree::{FindTreeResult, FoundNode, Node, NodeId, WorkspaceNode}; +use crate::utils::clonecell::CloneCell; use crate::utils::copyhashmap::CopyHashMap; use crate::utils::linkedlist::LinkedNode; +use crate::utils::queue::AsyncQueue; use crate::utils::smallmap::SmallMap; use crate::wire::WlSurfaceId; use crate::wire_xcon::CreateNotify; use crate::xwayland::XWaylandEvent; -use crate::{AsyncQueue, CloneCell, State}; use bstr::BString; use jay_config::Direction; use std::cell::{Cell, RefCell}; @@ -266,21 +268,37 @@ impl Xwindow { Change::None => {} Change::Unmap => self.destroy_node(true), Change::Map if self.data.info.override_redirect.get() => { - *self.display_link.borrow_mut() = Some(self.data.state.root.stacked.add_last(self.clone())); - *self.display_xlink.borrow_mut() = Some(self.data.state.root.xstacked.add_last(self.clone())); + *self.display_link.borrow_mut() = + Some(self.data.state.root.stacked.add_last(self.clone())); + *self.display_xlink.borrow_mut() = + Some(self.data.state.root.xstacked.add_last(self.clone())); self.data.state.tree_changed(); } Change::Map if self.data.info.wants_floating.get() => { - let ws = self.data.state.root.outputs.lock().iter().next().unwrap().1.workspace.get().unwrap(); + let ws = self + .data + .state + .root + .outputs + .lock() + .iter() + .next() + .unwrap() + .1 + .workspace + .get() + .unwrap(); // todo let ext = self.data.info.extents.get(); - self.data.state.map_floating(self.clone(), ext.width(), ext.height(), &ws); + self.data + .state + .map_floating(self.clone(), ext.width(), ext.height(), &ws); self.data.title_changed(); - }, + } Change::Map => { self.data.state.map_tiled(self.clone()); self.data.title_changed(); - }, + } } } } @@ -442,7 +460,20 @@ impl ToplevelNode for Xwindow { } fn toggle_floating(self: Rc) { - todo!() + let parent = match self.parent_node.get() { + Some(p) => p, + _ => return, + }; + if parent.is_float() { + parent.remove_child(&*self); + self.data.state.map_tiled(self.clone()); + } else if let Some(ws) = self.workspace.get() { + parent.remove_child(&*self); + let extents = self.data.info.extents.get(); + self.data + .state + .map_floating(self.clone(), extents.width(), extents.height(), &ws); + } } } diff --git a/src/ifs/wl_surface/zwlr_layer_surface_v1.rs b/src/ifs/wl_surface/zwlr_layer_surface_v1.rs index 6d36dac4..13e52c52 100644 --- a/src/ifs/wl_surface/zwlr_layer_surface_v1.rs +++ b/src/ifs/wl_surface/zwlr_layer_surface_v1.rs @@ -14,9 +14,9 @@ use crate::utils::bitflags::BitflagsExt; use crate::utils::buffd::MsgParser; use crate::utils::buffd::MsgParserError; use crate::utils::linkedlist::LinkedNode; +use crate::utils::numcell::NumCell; use crate::wire::zwlr_layer_surface_v1::*; use crate::wire::{WlSurfaceId, ZwlrLayerSurfaceV1Id}; -use crate::NumCell; use std::cell::Cell; use std::ops::Deref; use std::rc::Rc; diff --git a/src/ifs/zwp_linux_buffer_params_v1.rs b/src/ifs/zwp_linux_buffer_params_v1.rs index 8756397f..789ce290 100644 --- a/src/ifs/zwp_linux_buffer_params_v1.rs +++ b/src/ifs/zwp_linux_buffer_params_v1.rs @@ -5,11 +5,12 @@ use crate::ifs::wl_buffer::WlBuffer; use crate::ifs::zwp_linux_dmabuf_v1::ZwpLinuxDmabufV1; use crate::leaks::Tracker; use crate::object::Object; +use crate::render::RenderError; use crate::utils::buffd::MsgParser; use crate::utils::buffd::MsgParserError; +use crate::utils::errorfmt::ErrorFmt; use crate::wire::zwp_linux_buffer_params_v1::*; use crate::wire::{WlBufferId, ZwpLinuxBufferParamsV1Id}; -use crate::{ErrorFmt, RenderError}; use ahash::AHashMap; use std::cell::{Cell, RefCell}; use std::rc::Rc; diff --git a/src/keymap.xkb b/src/keymap.xkb index 456f22ae..8f0bfc47 100644 --- a/src/keymap.xkb +++ b/src/keymap.xkb @@ -120,19 +120,26 @@ xkb_keymap { type "ONE_LEVEL" { modifiers = none; + level_name[Level1] = "Base"; }; type "TWO_LEVEL" { modifiers = Shift; map[Shift] = Level2; + level_name[Level1] = "Base"; + level_name[Level2] = "Shift"; }; type "ALPHABETIC" { modifiers = Shift+Lock; map[Shift] = Level2; map[Lock] = Level2; + level_name[Level1] = "Base"; + level_name[Level2] = "Shift"; }; type "KEYPAD" { modifiers = Shift+Mod2; map[Mod2] = Level2; + level_name[Level1] = "Base"; + level_name[Level2] = "Shift"; }; }; diff --git a/src/libinput.rs b/src/libinput.rs index 3c1da9de..cbe95536 100644 --- a/src/libinput.rs +++ b/src/libinput.rs @@ -17,11 +17,11 @@ use crate::libinput::sys::{ libinput_path_add_device, libinput_path_create_context, libinput_unref, }; use crate::udev::UdevError; +use crate::utils::errorfmt::ErrorFmt; use crate::utils::oserror::OsError; use crate::utils::ptr_ext::PtrExt; use crate::utils::trim::AsciiTrim; use crate::utils::vasprintf::vasprintf_; -use crate::ErrorFmt; use bstr::ByteSlice; use std::ffi::{CStr, VaList}; use std::rc::Rc; diff --git a/src/logind.rs b/src/logind.rs index b0f6263a..ab3ecc84 100644 --- a/src/logind.rs +++ b/src/logind.rs @@ -1,7 +1,9 @@ -use crate::dbus::{DbusError, DbusSocket, SignalHandler}; -use crate::org::freedesktop::login1::seat::SwitchToReply; -use crate::org::freedesktop::login1::session::{PauseDevice, ResumeDevice, TakeDeviceReply}; -use crate::{org, FALSE}; +use crate::dbus::{DbusError, DbusSocket, SignalHandler, FALSE}; +use crate::wire_dbus::org; +use crate::wire_dbus::org::freedesktop::login1::seat::SwitchToReply; +use crate::wire_dbus::org::freedesktop::login1::session::{ + PauseDevice, ResumeDevice, TakeDeviceReply, +}; use std::rc::Rc; use thiserror::Error; use uapi::c; diff --git a/src/main.rs b/src/main.rs index d5e00925..985a4b3c 100644 --- a/src/main.rs +++ b/src/main.rs @@ -14,47 +14,9 @@ clippy::redundant_clone )] -use crate::acceptor::AcceptorError; -use crate::async_engine::{AsyncError, Phase}; -use crate::backends::metal; -use crate::client::Clients; -use crate::clientmem::ClientMemError; -use crate::dbus::{Dbus, FALSE}; -use crate::event_loop::EventLoopError; -use crate::forker::ForkerError; -use crate::globals::Globals; -use crate::ifs::wl_compositor::WlCompositorGlobal; -use crate::ifs::wl_shm::WlShmGlobal; -use crate::ifs::wl_subcompositor::WlSubcompositorGlobal; -use crate::ifs::wl_surface::NoneSurfaceExt; -use crate::ifs::xdg_wm_base::XdgWmBaseGlobal; -use crate::ifs::zwp_linux_dmabuf_v1::ZwpLinuxDmabufV1Global; -use crate::ifs::zxdg_decoration_manager_v1::ZxdgDecorationManagerV1Global; -use crate::render::RenderError; -use crate::sighand::SighandError; -use crate::state::State; -use crate::tree::{ - container_layout, container_render_data, float_layout, float_titles, DisplayNode, NodeIds, -}; -use crate::udev::Udev; -use crate::utils::clonecell::CloneCell; -use crate::utils::errorfmt::ErrorFmt; -use crate::utils::fdcloser::FdCloser; -use crate::utils::numcell::NumCell; -use crate::utils::queue::AsyncQueue; -use crate::utils::run_toplevel::RunToplevel; -use crate::wheel::WheelError; -use crate::wire_dbus::org; -use crate::xkbcommon::XkbContext; -use acceptor::Acceptor; -use async_engine::AsyncEngine; -use event_loop::EventLoop; -use log::LevelFilter; -use std::cell::Cell; -use std::ops::Deref; -use std::rc::Rc; -use thiserror::Error; -use wheel::Wheel; +use crate::cli::{Cli, Cmd}; +use crate::compositor::start_compositor; +use clap::Parser; #[macro_use] mod macros; @@ -65,8 +27,10 @@ mod async_engine; mod backend; mod backends; mod bugs; +mod cli; mod client; mod clientmem; +mod compositor; mod config; mod cursor; mod dbus; @@ -102,106 +66,10 @@ mod xkbcommon; mod xwayland; fn main() { - env_logger::builder() - .format_timestamp_millis() - .filter_level(LevelFilter::Info) - .filter_level(LevelFilter::Debug) - // .filter_level(LevelFilter::Trace) - .init(); - if let Err(e) = main_() { - log::error!("A fatal error occurred: {}", ErrorFmt(e)); - std::process::exit(1); + let cli: Cli = Cli::parse(); + println!("{:?}", cli); + match cli.command { + Cmd::Run => start_compositor(), + _ => {} } } - -#[derive(Debug, Error)] -enum MainError { - #[error("The client acceptor caused an error")] - AcceptorError(#[from] AcceptorError), - #[error("The event loop caused an error")] - EventLoopError(#[from] EventLoopError), - #[error("The signal handler caused an error")] - SighandError(#[from] SighandError), - #[error("The clientmem subsystem caused an error")] - ClientmemError(#[from] ClientMemError), - #[error("The timer subsystem caused an error")] - WheelError(#[from] WheelError), - #[error("The async subsystem caused an error")] - AsyncError(#[from] AsyncError), - #[error("The render backend caused an error")] - RenderError(#[from] RenderError), - #[error("The ol' forker caused an error")] - ForkerError(#[from] ForkerError), -} - -fn main_() -> Result<(), MainError> { - let forker = Rc::new(forker::ForkerProxy::create()?); - leaks::init(); - render::init()?; - clientmem::init()?; - let el = EventLoop::new()?; - sighand::install(&el)?; - let xkb_ctx = XkbContext::new().unwrap(); - let xkb_keymap = xkb_ctx.keymap_from_str(include_str!("keymap.xkb")).unwrap(); - let wheel = Wheel::install(&el)?; - let engine = AsyncEngine::install(&el, &wheel)?; - let (_run_toplevel_future, run_toplevel) = RunToplevel::install(&engine); - let node_ids = NodeIds::default(); - let state = Rc::new(State { - xkb_ctx, - backend: Default::default(), - forker: Default::default(), - default_keymap: xkb_keymap, - eng: engine.clone(), - el: el.clone(), - render_ctx: Default::default(), - cursors: Default::default(), - wheel, - clients: Clients::new(), - next_name: NumCell::new(1), - globals: Globals::new(), - output_ids: Default::default(), - root: Rc::new(DisplayNode::new(node_ids.next())), - node_ids, - backend_events: AsyncQueue::new(), - output_handlers: Default::default(), - seat_ids: Default::default(), - outputs: Default::default(), - seat_queue: Default::default(), - slow_clients: AsyncQueue::new(), - none_surface_ext: Rc::new(NoneSurfaceExt), - tree_changed_sent: Cell::new(false), - config: Default::default(), - input_device_ids: Default::default(), - input_device_handlers: Default::default(), - theme: Default::default(), - pending_container_layout: Default::default(), - pending_container_render_data: Default::default(), - pending_float_layout: Default::default(), - pending_float_titles: Default::default(), - dbus: Dbus::new(&engine, &run_toplevel), - fdcloser: FdCloser::new(), - }); - forker.install(&state); - let config = config::ConfigProxy::default(&state); - state.config.set(Some(Rc::new(config))); - let _global_event_handler = engine.spawn(tasks::handle_backend_events(state.clone())); - let _slow_client_handler = engine.spawn(tasks::handle_slow_clients(state.clone())); - let _container_do_layout = engine.spawn2(Phase::Layout, container_layout(state.clone())); - let _container_render_titles = - engine.spawn2(Phase::PostLayout, container_render_data(state.clone())); - let _float_do_layout = engine.spawn2(Phase::Layout, float_layout(state.clone())); - let _float_render_titles = engine.spawn2(Phase::PostLayout, float_titles(state.clone())); - let socket_path = Acceptor::install(&state)?; - forker.setenv(b"WAYLAND_DISPLAY", socket_path.as_bytes()); - let _xwayland = engine.spawn(xwayland::manage(state.clone())); - let _backend = engine.spawn(tasks::start_backend(state.clone())); - el.run()?; - drop(_xwayland); - state.clients.clear(); - for (_, seat) in state.globals.seats.lock().deref() { - seat.clear(); - } - leaks::log_leaked(); - Ok(()) -} diff --git a/src/render/renderer/framebuffer.rs b/src/render/renderer/framebuffer.rs index 5ea8400e..f7c09c24 100644 --- a/src/render/renderer/framebuffer.rs +++ b/src/render/renderer/framebuffer.rs @@ -6,8 +6,8 @@ use crate::render::gl::sys::{ use crate::render::renderer::context::RenderContext; use crate::render::renderer::renderer::Renderer; use crate::render::sys::{glBlendFunc, glFlush, GL_ONE, GL_ONE_MINUS_SRC_ALPHA}; +use crate::state::State; use crate::tree::Node; -use crate::State; use std::fmt::{Debug, Formatter}; use std::rc::Rc; diff --git a/src/render/renderer/image.rs b/src/render/renderer/image.rs index e76db41c..dcd305b4 100644 --- a/src/render/renderer/image.rs +++ b/src/render/renderer/image.rs @@ -1,7 +1,6 @@ use crate::render::egl::image::EglImage; use crate::render::gl::texture::GlTexture; -use crate::render::{RenderContext, Texture}; -use crate::RenderError; +use crate::render::{RenderContext, RenderError, Texture}; use std::rc::Rc; pub struct Image { diff --git a/src/render/renderer/renderer.rs b/src/render/renderer/renderer.rs index 9085e3e3..bbeba440 100644 --- a/src/render/renderer/renderer.rs +++ b/src/render/renderer/renderer.rs @@ -14,9 +14,9 @@ use crate::render::gl::sys::{ use crate::render::renderer::context::RenderContext; use crate::render::sys::{glDisable, glEnable, GL_BLEND}; use crate::render::Texture; +use crate::state::State; use crate::theme::Color; use crate::tree::{ContainerNode, FloatNode, Node, OutputNode, WorkspaceNode}; -use crate::State; use std::ops::Deref; use std::rc::Rc; diff --git a/src/sighand.rs b/src/sighand.rs index 282f2e50..6bca2657 100644 --- a/src/sighand.rs +++ b/src/sighand.rs @@ -1,5 +1,4 @@ -use crate::event_loop::{EventLoop, EventLoopDispatcher, EventLoopId}; -use crate::EventLoopError; +use crate::event_loop::{EventLoop, EventLoopDispatcher, EventLoopError, EventLoopId}; use std::error::Error; use std::rc::Rc; use thiserror::Error; diff --git a/src/state.rs b/src/state.rs index 680e28b8..013eb6bc 100644 --- a/src/state.rs +++ b/src/state.rs @@ -20,12 +20,13 @@ use crate::tree::{ }; use crate::utils::clonecell::CloneCell; use crate::utils::copyhashmap::CopyHashMap; +use crate::utils::errorfmt::ErrorFmt; use crate::utils::fdcloser::FdCloser; use crate::utils::linkedlist::LinkedList; use crate::utils::numcell::NumCell; use crate::utils::queue::AsyncQueue; -use crate::xkbcommon::XkbKeymap; -use crate::{ErrorFmt, Wheel, XkbContext}; +use crate::wheel::Wheel; +use crate::xkbcommon::{XkbContext, XkbKeymap}; use ahash::AHashMap; use std::cell::{Cell, RefCell}; use std::rc::Rc; diff --git a/src/tasks.rs b/src/tasks.rs index 4911c536..d9e1e0a2 100644 --- a/src/tasks.rs +++ b/src/tasks.rs @@ -4,9 +4,9 @@ mod output; mod slow_clients; mod start_backend; +use crate::state::State; use crate::tasks::backend::BackendEventHandler; use crate::tasks::slow_clients::SlowClientHandler; -use crate::State; pub use start_backend::start_backend; use std::rc::Rc; diff --git a/src/tasks/backend.rs b/src/tasks/backend.rs index 7111cd9e..137a2a29 100644 --- a/src/tasks/backend.rs +++ b/src/tasks/backend.rs @@ -1,7 +1,7 @@ use crate::backend::{BackendEvent, Output}; +use crate::state::State; use crate::tasks::input_device; use crate::tasks::output::OutputHandler; -use crate::State; use std::rc::Rc; pub struct BackendEventHandler { diff --git a/src/tasks/input_device.rs b/src/tasks/input_device.rs index 95f7f1b0..81753c29 100644 --- a/src/tasks/input_device.rs +++ b/src/tasks/input_device.rs @@ -1,7 +1,6 @@ use crate::backend::InputDevice; -use crate::state::{DeviceHandlerData, InputDeviceData}; +use crate::state::{DeviceHandlerData, InputDeviceData, State}; use crate::utils::asyncevent::AsyncEvent; -use crate::State; use std::rc::Rc; pub fn handle(state: &Rc, dev: Rc) { diff --git a/src/tasks/output.rs b/src/tasks/output.rs index 0fc7faae..45545151 100644 --- a/src/tasks/output.rs +++ b/src/tasks/output.rs @@ -1,10 +1,10 @@ use crate::backend::Output; use crate::ifs::wl_output::WlOutputGlobal; use crate::rect::Rect; +use crate::state::State; use crate::tree::{Node, OutputNode, WorkspaceNode}; use crate::utils::asyncevent::AsyncEvent; use crate::utils::clonecell::CloneCell; -use crate::State; use std::cell::{Cell, RefCell}; use std::rc::Rc; diff --git a/src/tasks/slow_clients.rs b/src/tasks/slow_clients.rs index 3831c193..c7411646 100644 --- a/src/tasks/slow_clients.rs +++ b/src/tasks/slow_clients.rs @@ -1,4 +1,4 @@ -use crate::State; +use crate::state::State; use std::rc::Rc; pub struct SlowClientHandler { diff --git a/src/tasks/start_backend.rs b/src/tasks/start_backend.rs index e559ed07..146c8546 100644 --- a/src/tasks/start_backend.rs +++ b/src/tasks/start_backend.rs @@ -1,5 +1,7 @@ +use crate::backends::metal; use crate::backends::x::XBackend; -use crate::{metal, ErrorFmt, State}; +use crate::state::State; +use crate::utils::errorfmt::ErrorFmt; use std::future::pending; use std::rc::Rc; diff --git a/src/text.rs b/src/text.rs index cada7e1d..3ba21475 100644 --- a/src/text.rs +++ b/src/text.rs @@ -3,9 +3,8 @@ use crate::pango::consts::{ CAIRO_FORMAT_ARGB32, CAIRO_OPERATOR_SOURCE, PANGO_ELLIPSIZE_END, PANGO_SCALE, }; use crate::pango::{CairoImageSurface, PangoError, PangoFontDescription}; -use crate::render::{RenderContext, Texture}; +use crate::render::{RenderContext, RenderError, Texture}; use crate::theme::Color; -use crate::RenderError; use std::rc::Rc; use thiserror::Error; diff --git a/src/tree.rs b/src/tree.rs index dd35c466..4e6fb9fe 100644 --- a/src/tree.rs +++ b/src/tree.rs @@ -10,8 +10,8 @@ use crate::render::Renderer; use crate::tree::walker::NodeVisitor; use crate::utils::copyhashmap::CopyHashMap; use crate::utils::linkedlist::LinkedList; +use crate::utils::numcell::NumCell; use crate::xkbcommon::ModifierState; -use crate::NumCell; pub use container::*; pub use float::*; use jay_config::Direction; diff --git a/src/tree/container.rs b/src/tree/container.rs index 89e43526..9b5c28cc 100644 --- a/src/tree/container.rs +++ b/src/tree/container.rs @@ -9,11 +9,14 @@ use crate::tree::walker::NodeVisitor; use crate::tree::{FindTreeResult, FoundNode, Node, NodeId, WorkspaceNode}; use crate::utils::clonecell::CloneCell; use crate::utils::linkedlist::{LinkedList, LinkedNode, NodeRef}; -use crate::{text, ErrorFmt, NumCell, State}; use ahash::AHashMap; use jay_config::{Axis, Direction}; use std::cell::{Cell, RefCell}; +use crate::state::State; +use crate::text; +use crate::utils::errorfmt::ErrorFmt; +use crate::utils::numcell::NumCell; use std::fmt::{Debug, Formatter}; use std::mem; use std::ops::{Deref, DerefMut, Sub}; diff --git a/src/tree/float.rs b/src/tree/float.rs index 2b44c817..726cc751 100644 --- a/src/tree/float.rs +++ b/src/tree/float.rs @@ -4,11 +4,14 @@ use crate::fixed::Fixed; use crate::ifs::wl_seat::{NodeSeatState, SeatId, WlSeatGlobal, BTN_LEFT}; use crate::rect::Rect; use crate::render::{Renderer, Texture}; +use crate::state::State; +use crate::text; use crate::theme::Color; use crate::tree::walker::NodeVisitor; use crate::tree::{FindTreeResult, FoundNode, Node, NodeId, WorkspaceNode}; +use crate::utils::clonecell::CloneCell; +use crate::utils::errorfmt::ErrorFmt; use crate::utils::linkedlist::LinkedNode; -use crate::{text, CloneCell, ErrorFmt, State}; use ahash::AHashMap; use std::cell::{Cell, RefCell}; use std::fmt::{Debug, Formatter}; diff --git a/src/tree/output.rs b/src/tree/output.rs index 5eead285..7d4d193d 100644 --- a/src/tree/output.rs +++ b/src/tree/output.rs @@ -5,9 +5,9 @@ use crate::ifs::wl_surface::zwlr_layer_surface_v1::ZwlrLayerSurfaceV1; use crate::rect::Rect; use crate::render::Renderer; use crate::tree::walker::NodeVisitor; -use crate::tree::{FindTreeResult, FoundNode, Node, NodeId, WorkspaceNode}; +use crate::tree::{DisplayNode, FindTreeResult, FoundNode, Node, NodeId, WorkspaceNode}; +use crate::utils::clonecell::CloneCell; use crate::utils::linkedlist::LinkedList; -use crate::{CloneCell, DisplayNode}; use std::cell::{Cell, RefCell}; use std::fmt::{Debug, Formatter}; use std::ops::Deref; diff --git a/src/tree/toplevel.rs b/src/tree/toplevel.rs index 16f5a0e8..782d4d8e 100644 --- a/src/tree/toplevel.rs +++ b/src/tree/toplevel.rs @@ -1,10 +1,10 @@ -use crate::ifs::wl_seat::{SeatId}; +use crate::ifs::wl_seat::SeatId; use crate::ifs::wl_surface::WlSurface; use crate::tree::{Node, WorkspaceNode}; use crate::utils::linkedlist::LinkedNode; -use std::rc::Rc; -use crate::NumCell; +use crate::utils::numcell::NumCell; use crate::utils::smallmap::SmallMap; +use std::rc::Rc; pub trait ToplevelNode { fn data(&self) -> &ToplevelData; diff --git a/src/tree/walker.rs b/src/tree/walker.rs index 85ee44d1..ae8d4079 100644 --- a/src/tree/walker.rs +++ b/src/tree/walker.rs @@ -3,8 +3,7 @@ use crate::ifs::wl_surface::xdg_surface::xdg_toplevel::XdgToplevel; use crate::ifs::wl_surface::xwindow::Xwindow; use crate::ifs::wl_surface::zwlr_layer_surface_v1::ZwlrLayerSurfaceV1; use crate::ifs::wl_surface::WlSurface; -use crate::tree::{ContainerNode, FloatNode, Node, OutputNode, WorkspaceNode}; -use crate::DisplayNode; +use crate::tree::{ContainerNode, DisplayNode, FloatNode, Node, OutputNode, WorkspaceNode}; use std::rc::Rc; pub trait NodeVisitorBase: Sized { diff --git a/src/utils/asyncevent.rs b/src/utils/asyncevent.rs index 20b1faa5..a062b275 100644 --- a/src/utils/asyncevent.rs +++ b/src/utils/asyncevent.rs @@ -1,4 +1,4 @@ -use crate::NumCell; +use crate::utils::numcell::NumCell; use std::cell::Cell; use std::future::Future; use std::pin::Pin; diff --git a/src/utils/bufio.rs b/src/utils/bufio.rs index 628c693b..aa2ba363 100644 --- a/src/utils/bufio.rs +++ b/src/utils/bufio.rs @@ -1,9 +1,9 @@ -use crate::async_engine::AsyncFd; +use crate::async_engine::{AsyncError, AsyncFd}; use crate::utils::oserror::OsError; +use crate::utils::queue::AsyncQueue; use crate::utils::stack::Stack; use crate::utils::vec_ext::{UninitVecExt, VecExt}; use crate::utils::vecstorage::VecStorage; -use crate::{AsyncError, AsyncQueue}; use std::collections::VecDeque; use std::mem; use std::mem::MaybeUninit; diff --git a/src/utils/linkedlist.rs b/src/utils/linkedlist.rs index d01b1d6f..0d7cb664 100644 --- a/src/utils/linkedlist.rs +++ b/src/utils/linkedlist.rs @@ -1,5 +1,5 @@ +use crate::utils::numcell::NumCell; use crate::utils::ptr_ext::PtrExt; -use crate::NumCell; use std::cell::Cell; use std::fmt::{Debug, Formatter}; use std::mem; diff --git a/src/utils/run_toplevel.rs b/src/utils/run_toplevel.rs index dc1b0466..7552c8f2 100644 --- a/src/utils/run_toplevel.rs +++ b/src/utils/run_toplevel.rs @@ -1,5 +1,5 @@ -use crate::async_engine::SpawnedFuture; -use crate::{AsyncEngine, AsyncQueue}; +use crate::async_engine::{AsyncEngine, SpawnedFuture}; +use crate::utils::queue::AsyncQueue; use std::rc::Rc; pub struct RunToplevelFuture { diff --git a/src/xcon.rs b/src/xcon.rs index 5399dff7..c1d3ab98 100644 --- a/src/xcon.rs +++ b/src/xcon.rs @@ -1,6 +1,10 @@ -use crate::async_engine::SpawnedFuture; +use crate::async_engine::{AsyncEngine, AsyncError, Phase, SpawnedFuture}; use crate::utils::bufio::{BufIo, BufIoError, BufIoMessage}; +use crate::utils::clonecell::CloneCell; +use crate::utils::errorfmt::ErrorFmt; +use crate::utils::numcell::NumCell; use crate::utils::oserror::OsError; +use crate::utils::queue::AsyncQueue; use crate::utils::vec_ext::VecExt; use crate::wire_xcon::{ CreateGC, CreatePixmap, Extension, FreeGC, FreePixmap, GetInputFocus, GetProperty, @@ -15,12 +19,12 @@ pub use crate::xcon::parser::Parser; use crate::xcon::wire_type::SendEvent; pub use crate::xcon::wire_type::{Message, Request, XEvent}; use crate::xcon::xauthority::{XAuthority, LOCAL, MIT_MAGIC_COOKIE}; -use crate::{AsyncEngine, AsyncError, AsyncQueue, CloneCell, ErrorFmt, NumCell, Phase}; use ahash::AHashMap; use bstr::{BString, ByteSlice}; use std::any::TypeId; use std::cell::{Cell, RefCell}; use std::collections::VecDeque; +use std::fmt::Debug; use std::future::Future; use std::io::Write; use std::mem::MaybeUninit; @@ -29,7 +33,6 @@ use std::pin::Pin; use std::rc::{Rc, Weak}; use std::task::{Context, Poll, Waker}; use std::{mem, ptr}; -use std::fmt::Debug; use thiserror::Error; use uapi::{c, OwnedFd}; @@ -172,7 +175,8 @@ pub struct Reply> { } impl> Debug for Reply - where T::Generic<'static>: Debug +where + T::Generic<'static>: Debug, { fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { self.t.fmt(f) @@ -260,7 +264,10 @@ impl> AsyncReplyHandler { waker.wake(); } } else if let Err(e) = res { - log::error!("Received an error whose handler has already been dropped: {}", ErrorFmt(e)); + log::error!( + "Received an error whose handler has already been dropped: {}", + ErrorFmt(e) + ); } } } diff --git a/src/xcon/consts.rs b/src/xcon/consts.rs index fb2c12a4..5a25f379 100644 --- a/src/xcon/consts.rs +++ b/src/xcon/consts.rs @@ -217,37 +217,37 @@ pub const INPUT_FOCUS_POINTER_ROOT: u8 = 1; pub const INPUT_FOCUS_PARENT: u8 = 2; pub const INPUT_FOCUS_FOLLOW_KEYBOARD: u8 = 3; -pub const NOTIFY_MODE_NORMAL :u8 = 0; -pub const NOTIFY_MODE_GRAB :u8 = 1; -pub const NOTIFY_MODE_UNGRAB :u8 = 2; -pub const NOTIFY_MODE_WHILE_GRABBED :u8 = 3; +pub const NOTIFY_MODE_NORMAL: u8 = 0; +pub const NOTIFY_MODE_GRAB: u8 = 1; +pub const NOTIFY_MODE_UNGRAB: u8 = 2; +pub const NOTIFY_MODE_WHILE_GRABBED: u8 = 3; -pub const NOTIFY_DETAIL_ANCESTOR : u8 = 0; -pub const NOTIFY_DETAIL_VIRTUAL : u8 = 1; -pub const NOTIFY_DETAIL_INFERIOR : u8 = 2; -pub const NOTIFY_DETAIL_NONLINEAR : u8 = 3; -pub const NOTIFY_DETAIL_NONLINEAR_VIRTUAL : u8 = 4; -pub const NOTIFY_DETAIL_POINTER : u8 = 5; -pub const NOTIFY_DETAIL_POINTER_ROOT : u8 = 6; -pub const NOTIFY_DETAIL_NONE : u8 = 7; +pub const NOTIFY_DETAIL_ANCESTOR: u8 = 0; +pub const NOTIFY_DETAIL_VIRTUAL: u8 = 1; +pub const NOTIFY_DETAIL_INFERIOR: u8 = 2; +pub const NOTIFY_DETAIL_NONLINEAR: u8 = 3; +pub const NOTIFY_DETAIL_NONLINEAR_VIRTUAL: u8 = 4; +pub const NOTIFY_DETAIL_POINTER: u8 = 5; +pub const NOTIFY_DETAIL_POINTER_ROOT: u8 = 6; +pub const NOTIFY_DETAIL_NONE: u8 = 7; -pub const ICCCM_WM_STATE_WITHDRAWN : u32 = 0; -pub const ICCCM_WM_STATE_NORMAL : u32 = 1; -pub const ICCCM_WM_STATE_ICONIC : u32 = 3; +pub const ICCCM_WM_STATE_WITHDRAWN: u32 = 0; +pub const ICCCM_WM_STATE_NORMAL: u32 = 1; +pub const ICCCM_WM_STATE_ICONIC: u32 = 3; pub const _NET_WM_STATE_REMOVE: u32 = 0; pub const _NET_WM_STATE_ADD: u32 = 1; pub const _NET_WM_STATE_TOGGLE: u32 = 2; -pub const _NET_WM_MOVERESIZE_SIZE_TOPLEFT : u32 = 0; -pub const _NET_WM_MOVERESIZE_SIZE_TOP : u32 = 1; -pub const _NET_WM_MOVERESIZE_SIZE_TOPRIGHT : u32 = 2; -pub const _NET_WM_MOVERESIZE_SIZE_RIGHT : u32 = 3; -pub const _NET_WM_MOVERESIZE_SIZE_BOTTOMRIGHT : u32 = 4; -pub const _NET_WM_MOVERESIZE_SIZE_BOTTOM : u32 = 5; -pub const _NET_WM_MOVERESIZE_SIZE_BOTTOMLEFT : u32 = 6; -pub const _NET_WM_MOVERESIZE_SIZE_LEFT : u32 = 7; -pub const _NET_WM_MOVERESIZE_MOVE : u32 = 8; -pub const _NET_WM_MOVERESIZE_SIZE_KEYBOARD : u32 = 9; -pub const _NET_WM_MOVERESIZE_MOVE_KEYBOARD : u32 = 10; -pub const _NET_WM_MOVERESIZE_CANCEL : u32 = 11; +pub const _NET_WM_MOVERESIZE_SIZE_TOPLEFT: u32 = 0; +pub const _NET_WM_MOVERESIZE_SIZE_TOP: u32 = 1; +pub const _NET_WM_MOVERESIZE_SIZE_TOPRIGHT: u32 = 2; +pub const _NET_WM_MOVERESIZE_SIZE_RIGHT: u32 = 3; +pub const _NET_WM_MOVERESIZE_SIZE_BOTTOMRIGHT: u32 = 4; +pub const _NET_WM_MOVERESIZE_SIZE_BOTTOM: u32 = 5; +pub const _NET_WM_MOVERESIZE_SIZE_BOTTOMLEFT: u32 = 6; +pub const _NET_WM_MOVERESIZE_SIZE_LEFT: u32 = 7; +pub const _NET_WM_MOVERESIZE_MOVE: u32 = 8; +pub const _NET_WM_MOVERESIZE_SIZE_KEYBOARD: u32 = 9; +pub const _NET_WM_MOVERESIZE_MOVE_KEYBOARD: u32 = 10; +pub const _NET_WM_MOVERESIZE_CANCEL: u32 = 11; diff --git a/src/xcon/incoming.rs b/src/xcon/incoming.rs index fbcbadc4..bb595ba7 100644 --- a/src/xcon/incoming.rs +++ b/src/xcon/incoming.rs @@ -1,7 +1,7 @@ use crate::utils::bufio::BufIoIncoming; +use crate::utils::errorfmt::ErrorFmt; use crate::xcon::consts::XGE_EVENT; use crate::xcon::{Event, ExtensionData, ExtensionIdRange, Parser, XconData, XconError}; -use crate::ErrorFmt; use std::mem; use std::rc::Rc; diff --git a/src/xcon/outgoing.rs b/src/xcon/outgoing.rs index 8452a940..1cbe1269 100644 --- a/src/xcon/outgoing.rs +++ b/src/xcon/outgoing.rs @@ -1,5 +1,5 @@ +use crate::utils::errorfmt::ErrorFmt; use crate::xcon::XconData; -use crate::ErrorFmt; use std::rc::Rc; pub(super) async fn handle_outgoing(socket: Rc) { diff --git a/src/xwayland.rs b/src/xwayland.rs index 61393800..6a05ec31 100644 --- a/src/xwayland.rs +++ b/src/xwayland.rs @@ -1,17 +1,20 @@ mod xsocket; mod xwm; +use crate::async_engine::AsyncError; use crate::client::ClientError; -use crate::forker::ForkerProxy; +use crate::forker::{ForkerError, ForkerProxy}; use crate::ifs::wl_surface::xwindow::{Xwindow, XwindowData}; use crate::ifs::wl_surface::WlSurface; +use crate::state::State; +use crate::utils::errorfmt::ErrorFmt; use crate::utils::oserror::OsError; +use crate::utils::queue::AsyncQueue; use crate::utils::tri::Try; use crate::wire::WlSurfaceId; use crate::xcon::XconError; use crate::xwayland::xsocket::allocate_socket; use crate::xwayland::xwm::Wm; -use crate::{AsyncError, AsyncQueue, ErrorFmt, ForkerError, State}; use bstr::ByteSlice; use std::num::ParseIntError; use std::rc::Rc; diff --git a/src/xwayland/xsocket.rs b/src/xwayland/xsocket.rs index 4236dbdb..34eba3db 100644 --- a/src/xwayland/xsocket.rs +++ b/src/xwayland/xsocket.rs @@ -1,5 +1,5 @@ +use crate::utils::errorfmt::ErrorFmt; use crate::xwayland::XWaylandError; -use crate::ErrorFmt; use std::io::{Read, Write}; use std::rc::Rc; use uapi::{c, format_ustr, Errno, OwnedFd, Ustring}; diff --git a/src/xwayland/xwm.rs b/src/xwayland/xwm.rs index 1062a21a..a64c9dab 100644 --- a/src/xwayland/xwm.rs +++ b/src/xwayland/xwm.rs @@ -2,24 +2,41 @@ use crate::client::Client; use crate::ifs::wl_surface::xwindow::{XInputModel, Xwindow, XwindowData}; use crate::ifs::wl_surface::WlSurface; use crate::rect::Rect; +use crate::state::State; +use crate::tree::Node; use crate::utils::bitflags::BitflagsExt; +use crate::utils::errorfmt::ErrorFmt; +use crate::utils::linkedlist::LinkedList; +use crate::utils::queue::AsyncQueue; use crate::wire::WlSurfaceId; -use crate::wire_xcon::{ChangeProperty, ChangeWindowAttributes, ClientMessage, CompositeRedirectSubwindows, ConfigureNotify, ConfigureRequest, ConfigureWindow, ConfigureWindowValues, CreateNotify, CreateWindow, CreateWindowValues, DestroyNotify, FocusIn, GetGeometry, InternAtom, KillClient, MapNotify, MapRequest, MapWindow, PropertyNotify, ResClientIdSpec, ResQueryClientIds, SetInputFocus, SetSelectionOwner, UnmapNotify}; -use crate::xcon::consts::{_NET_WM_STATE_ADD, _NET_WM_STATE_REMOVE, _NET_WM_STATE_TOGGLE, ATOM_ATOM, ATOM_STRING, ATOM_WINDOW, ATOM_WM_CLASS, ATOM_WM_NAME, ATOM_WM_SIZE_HINTS, ATOM_WM_TRANSIENT_FOR, COMPOSITE_REDIRECT_MANUAL, EVENT_MASK_FOCUS_CHANGE, EVENT_MASK_PROPERTY_CHANGE, EVENT_MASK_SUBSTRUCTURE_NOTIFY, EVENT_MASK_SUBSTRUCTURE_REDIRECT, ICCCM_WM_HINT_INPUT, ICCCM_WM_STATE_ICONIC, ICCCM_WM_STATE_NORMAL, ICCCM_WM_STATE_WITHDRAWN, INPUT_FOCUS_POINTER_ROOT, MWM_HINTS_DECORATIONS_FIELD, MWM_HINTS_FLAGS_FIELD, NOTIFY_DETAIL_POINTER, NOTIFY_MODE_GRAB, NOTIFY_MODE_UNGRAB, PROP_MODE_REPLACE, RES_CLIENT_ID_MASK_LOCAL_CLIENT_PID, WINDOW_CLASS_INPUT_OUTPUT}; +use crate::wire_xcon::{ + ChangeProperty, ChangeWindowAttributes, ClientMessage, CompositeRedirectSubwindows, + ConfigureNotify, ConfigureRequest, ConfigureWindow, ConfigureWindowValues, CreateNotify, + CreateWindow, CreateWindowValues, DestroyNotify, FocusIn, GetGeometry, InternAtom, KillClient, + MapNotify, MapRequest, MapWindow, PropertyNotify, ResClientIdSpec, ResQueryClientIds, + SetInputFocus, SetSelectionOwner, UnmapNotify, +}; +use crate::xcon::consts::{ + ATOM_ATOM, ATOM_STRING, ATOM_WINDOW, ATOM_WM_CLASS, ATOM_WM_NAME, ATOM_WM_SIZE_HINTS, + ATOM_WM_TRANSIENT_FOR, COMPOSITE_REDIRECT_MANUAL, EVENT_MASK_FOCUS_CHANGE, + EVENT_MASK_PROPERTY_CHANGE, EVENT_MASK_SUBSTRUCTURE_NOTIFY, EVENT_MASK_SUBSTRUCTURE_REDIRECT, + ICCCM_WM_HINT_INPUT, ICCCM_WM_STATE_ICONIC, ICCCM_WM_STATE_NORMAL, ICCCM_WM_STATE_WITHDRAWN, + INPUT_FOCUS_POINTER_ROOT, MWM_HINTS_DECORATIONS_FIELD, MWM_HINTS_FLAGS_FIELD, + NOTIFY_DETAIL_POINTER, NOTIFY_MODE_GRAB, NOTIFY_MODE_UNGRAB, PROP_MODE_REPLACE, + RES_CLIENT_ID_MASK_LOCAL_CLIENT_PID, WINDOW_CLASS_INPUT_OUTPUT, _NET_WM_STATE_ADD, + _NET_WM_STATE_REMOVE, _NET_WM_STATE_TOGGLE, +}; use crate::xcon::{Event, XEvent, Xcon, XconError}; use crate::xwayland::{XWaylandError, XWaylandEvent}; -use crate::{AsyncQueue, ErrorFmt, State}; use ahash::{AHashMap, AHashSet}; +use bstr::ByteSlice; use futures_util::{select, FutureExt}; use smallvec::SmallVec; use std::borrow::Cow; use std::mem; use std::ops::{Deref, DerefMut}; use std::rc::Rc; -use bstr::ByteSlice; use uapi::OwnedFd; -use crate::tree::Node; -use crate::utils::linkedlist::LinkedList; atoms! { Atoms; @@ -320,7 +337,7 @@ impl Wm { stack_list: Default::default(), num_stacked: 0, map_list: Default::default(), - num_mapped: 0 + num_mapped: 0, }) } @@ -513,7 +530,10 @@ impl Wm { return; } Err(e) => { - log::error!("Could not retrieve WM_WINDOW_ROLE property: {}", ErrorFmt(e)); + log::error!( + "Could not retrieve WM_WINDOW_ROLE property: {}", + ErrorFmt(e) + ); return; } } @@ -587,9 +607,16 @@ impl Wm { async fn load_window_wm_transient_for(&self, data: &Rc) { let mut buf = vec![]; - if let Err(e) = self.c.get_property::(data.window_id, ATOM_WM_TRANSIENT_FOR, ATOM_WINDOW, &mut buf).await { + if let Err(e) = self + .c + .get_property::(data.window_id, ATOM_WM_TRANSIENT_FOR, ATOM_WINDOW, &mut buf) + .await + { if !matches!(e, XconError::PropertyUnavailable) { - log::error!("Could not retrieve WM_TRANSIENT_FOR property: {}", ErrorFmt(e)); + log::error!( + "Could not retrieve WM_TRANSIENT_FOR property: {}", + ErrorFmt(e) + ); } } if let Some(old) = data.parent.take() { @@ -940,7 +967,10 @@ impl Wm { if let Some(prev) = focus_window { let prev_pid = prev.info.pid.get(); let new_pid = window.info.pid.get(); - if prev_pid.is_some() && prev_pid == new_pid && revent.serial() >= self.last_input_serial { + if prev_pid.is_some() + && prev_pid == new_pid + && revent.serial() >= self.last_input_serial + { focus_window = new_window; } } @@ -952,9 +982,12 @@ impl Wm { async fn close_window(&mut self, window: &Rc) { if window.info.protocols.contains(&self.atoms.WM_DELETE_WINDOW) { - self.send_wm_message(window, 0, &[self.atoms.WM_DELETE_WINDOW]).await; + self.send_wm_message(window, 0, &[self.atoms.WM_DELETE_WINDOW]) + .await; } else { - self.c.call(&KillClient { resource: window.window_id }); + self.c.call(&KillClient { + resource: window.window_id, + }); } } @@ -963,7 +996,7 @@ impl Wm { return; } if let Some(w) = window { - if w.destroyed.get() && w.info.override_redirect.get() { + if w.destroyed.get() || w.info.override_redirect.get() { return; } if w.info.minimized.get() { @@ -1104,7 +1137,9 @@ impl Wm { self.handle_net_wm_state(&event).await?; } else if event.ty == self.atoms._NET_ACTIVE_WINDOW { self.handle_net_active_window(&event).await?; - } else if event.ty == self.atoms._NET_STARTUP_INFO || event.ty == self.atoms._NET_STARTUP_INFO_BEGIN { + } else if event.ty == self.atoms._NET_STARTUP_INFO + || event.ty == self.atoms._NET_STARTUP_INFO_BEGIN + { self.handle_net_startup_info(&event).await?; } else if event.ty == self.atoms.WM_CHANGE_STATE { self.handle_wm_change_state(&event).await?; @@ -1182,7 +1217,11 @@ impl Wm { }; self.set_wm_state(&data, ICCCM_WM_STATE_NORMAL).await; self.set_net_wm_state(&data).await; - if data.map_link.replace(Some(self.map_list.add_last(data.clone()))).is_none() { + if data + .map_link + .replace(Some(self.map_list.add_last(data.clone()))) + .is_none() + { self.num_mapped += 1; } self.set_net_client_list().await; @@ -1196,7 +1235,12 @@ impl Wm { Ok(()) } - async fn stack_window(&mut self, window: &Rc, sibling: Option<&Rc>, above: bool) { + async fn stack_window( + &mut self, + window: &Rc, + sibling: Option<&Rc>, + above: bool, + ) { let link = 'link: { if let Some(s) = sibling { if s.window_id == window.window_id { @@ -1249,7 +1293,7 @@ impl Wm { event.width as _, event.height as _, ) - .unwrap(); + .unwrap(); let changed = data.info.extents.replace(extents) != extents; if changed { self.state.tree_changed(); @@ -1286,18 +1330,31 @@ impl Wm { &mut self, event: &ClientMessage<'_>, ) -> Result<(), XWaylandError> { - let _data = match self.windows.get(&event.window) { + let data = match self.windows.get(&event.window) { Some(d) => d, _ => return Ok(()), }; - let _minimize = match event.data[0] { + let minimize = match event.data[0] { ICCCM_WM_STATE_NORMAL => false, - ICCCM_WM_STATE_ICONIC => true, + ICCCM_WM_STATE_ICONIC => self.handle_minimize_requested(data).await, _ => return Ok(()), }; + data.info.minimized.set(minimize); + self.set_net_wm_state(data).await; Ok(()) } + async fn handle_minimize_requested(&self, data: &Rc) -> bool { + if let Some(w) = data.window.get() { + if w.toplevel_data.active_surfaces.get() > 0 { + self.set_wm_state(data, ICCCM_WM_STATE_NORMAL).await; + return false; + } + } + self.set_wm_state(data, ICCCM_WM_STATE_ICONIC).await; + true + } + async fn handle_net_startup_info( &mut self, event: &ClientMessage<'_>, @@ -1330,11 +1387,25 @@ impl Wm { &mut self, event: &ClientMessage<'_>, ) -> Result<(), XWaylandError> { - let _data = match self.windows.get(&event.window) { + let data = match self.windows.get(&event.window) { Some(d) => d, _ => return Ok(()), }; - // TODO activate + let fw = match &self.focus_window { + Some(w) => w, + _ => return Ok(()), + }; + if data.info.pid.get().is_none() || data.info.pid.get() != fw.info.pid.get() { + return Ok(()); + } + let win = match data.window.get() { + Some(w) => w, + _ => return Ok(()), + }; + let seats = self.state.globals.seats.lock(); + for (_, seat) in seats.deref() { + seat.focus_toplevel(win.clone()); + } Ok(()) } @@ -1380,6 +1451,11 @@ impl Wm { if !changed { return Ok(()); } + if minimized != data.info.minimized.get() { + if minimized { + minimized = self.handle_minimize_requested(data).await; + } + } data.info.fullscreen.set(fullscreen); data.info.maximized_horz.set(maximized_horz); data.info.maximized_vert.set(maximized_vert); @@ -1415,10 +1491,22 @@ impl Wm { fn update_wants_floating(&self, data: &Rc) { let res = false || data.info.modal.get() - || data.info.window_types.contains(&self.atoms._NET_WM_WINDOW_TYPE_DIALOG) - || data.info.window_types.contains(&self.atoms._NET_WM_WINDOW_TYPE_UTILITY) - || data.info.window_types.contains(&self.atoms._NET_WM_WINDOW_TYPE_TOOLBAR) - || data.info.window_types.contains(&self.atoms._NET_WM_WINDOW_TYPE_SPLASH) + || data + .info + .window_types + .contains(&self.atoms._NET_WM_WINDOW_TYPE_DIALOG) + || data + .info + .window_types + .contains(&self.atoms._NET_WM_WINDOW_TYPE_UTILITY) + || data + .info + .window_types + .contains(&self.atoms._NET_WM_WINDOW_TYPE_TOOLBAR) + || data + .info + .window_types + .contains(&self.atoms._NET_WM_WINDOW_TYPE_SPLASH) || { let max_w = data.info.normal_hints.max_width.get(); let min_w = data.info.normal_hints.min_width.get();